diff --git a/.gitignore b/.gitignore
index 747968848..c3c539d61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
"cps/"
node_modules/
+*.env
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 9053f7386..000000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Contributing to Personalized Learning Path
-
-Thanks for considering contributing! Please follow these steps:
-
-1. Fork the repository.
-2. Create your feature branch: `git checkout -b feature/your-feature-name`.
-3. Commit your changes: `git commit -m "Add some feature"`.
-4. Push to the branch: `git push origin feature/your-feature-name`.
-5. Open a Pull Request on GitHub and describe your changes clearly.
-
-Please ensure your code follows existing style and you add meaningful commit messages.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index ca1191330..000000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2025 bhavitha9052004
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..70b515342
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# π CPS Personalized Learning System Using Knowledge Graph
+An AI-powered platform that delivers personalized learning paths using knowledge graphs and adaptive quizzes.
+
+## π Features
+- User Authentication
+- Personalized Recommendations via Concept Graph
+- Quiz Generation using GPT-4o (RAG)
+- Mastery-based Weight Updates
+- Progress Visualization
+
+## π§ How It Works
+1. User selects learned and target topics.
+2. System finds shortest path using the concept graph.
+3. Quizzes are generated per topic using RAG.
+4. Scores update mastery weights between 0.1β0.9.
+5. Future recommendations adapt based on mastery.
+
+## π Tech Stack
+| Tech | Purpose |
+|--------------|--------------------------------------|
+| React + TypeScript | Frontend |
+| Node.js + Express | Backend APIs |
+| MongoDB | Persistent storage |
+| OpenAI GPT-4o | Quiz generation using RAG |
+| Zustand | Global state management |
+| Tailwind CSS | UI styling |
+
+
+## π Project Structure
+client/
+server/
+data/
+
+
+## π¦ Setup & Installation
+
+1. Clone the repo
+2. Install dependencies
+3. Setup environment variables
+4. Run dev servers
+ {(cd client;npm run dev)
+(cd server;npm run dev)---> All set!!
+ensure the portno. of client to be 5173}
+
+## π Future Enhancements
+- Gamification badges
+- Teacher dashboard
+- More granular topic-level quizzes
+- Enhance recommendation engine on advanced DSA topics
+- UI improvements as always
+
+
+## π Acknowledgments
+- MIT OCW for scraped content
+- OpenAI for GPT-4o API
+-IIT Ropar for the mentor and tech supoort and a lovely team.
+
+
+
+## π License
+This project is licensed under the MIT License.
diff --git a/cg_visualization.py b/cg_visualization.py
deleted file mode 100644
index 45d2c88d3..000000000
--- a/cg_visualization.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from pyvis.network import Network
-import networkx as nx
-import json
-from networkx.readwrite import json_graph
-
-with open("concept_graph_full.json", "r", encoding="utf-8") as f:
- data = json.load(f)
-G_loaded = json_graph.node_link_graph(data)
-
-# Created a pyvis network
-net = Network(
- height="800px",
- width="100%",
- bgcolor="#ffffff",
- font_color=True,
- directed=True
-)
-
-# Converted from networkx
-net.from_nx(G_loaded)
-#node properties
-for node in net.nodes:
- node["size"] = 20
- node["color"] = "#97C2FC"
- node["borderWidth"] = 2
- node["borderColor"] = "#2B7CE9"
- node["font"] = {"size": 12}
-
-# edge properties
-for edge in net.edges:
- edge["color"] = "#848484"
- edge["smooth"] = {"type": "continuous"}
- edge["arrows"] = "to"
- edge["arrows"] = {"to": {"enabled": True, "scaleFactor": 0.5}}
-
-# Configure dynamics
-net.set_options("""
- var options = {
- "physics": {
- "enabled": true,
- "stabilization": {"iterations": 100},
- "barnesHut": {
- "gravitationalConstant": -2000,
- "springConstant": 0.04,
- "springLength": 95
- }
- }
- }
-""")
-
-# Saved the graph
-try:
- net.write_html("concept_graph.html")
- print("Graph has been saved as 'concept_graph.html'. Please open it in a web browser to view.")
-except Exception as e:
- print(f"Error saving graph: {str(e)}")
diff --git a/concept-graph.py b/concept-graph.py
deleted file mode 100644
index 008ccac1f..000000000
--- a/concept-graph.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import networkx as nx
-import matplotlib.pyplot as plt
-import json
-from networkx.readwrite import json_graph
-concept_map = {
- "What is computation?": ["Computation", "Algorithms", "Problem Solving"],
- "Branching and Iteration": ["Conditionals", "Loops", "Control Flow"],
- "String Manipulation, Guess and Check, Approximations, Bisection": [
- "String Manipulation", "Guess and Check", "Approximation", "Bisection Search"
- ],
- "Decomposition, Abstractions, Functions": ["Decomposition", "Abstraction", "Functions"],
- "Tuples, Lists, Aliasing, Mutability, Cloning": [
- "Tuples", "Lists", "Aliasing", "Mutability", "Cloning"
- ],
- "Recursion, Dictionaries": ["Recursion", "Dictionaries"],
- "Testing, Debugging, Exceptions, Assertions": [
- "Testing", "Debugging", "Exceptions", "Assertions"
- ],
- "Object Oriented Programming": ["Classes", "OOP", "Encapsulation"],
- "Python Classes and Inheritance": ["Inheritance", "Subclasses", "Class Hierarchies"],
- "Understanding Program Efficiency, Part 1": ["Big-O Notation", "Efficiency"],
- "Understanding Program Efficiency, Part 2": ["Efficiency", "Space Complexity"],
- "Searching and Sorting": ["Search Algorithms", "Sorting Algorithms"],
-}
-
-G = nx.DiGraph()
-
-# Converted concept_map to a list of concept lists in lecture order
-concept_lists = list(concept_map.values())
-
-# graph
-for i, concepts in enumerate(concept_lists):
- # Connected all concepts within the same lecture in sequence
- for j in range(len(concepts) - 1):
- G.add_edge(concepts[j], concepts[j + 1])
-
- # Connected last concept of this lecture to all concepts in the next lecture
- if i < len(concept_lists) - 1:
- last_concept = concepts[-1]
- next_concepts = concept_lists[i + 1]
- for next_concept in next_concepts:
- G.add_edge(last_concept, next_concept)
-
-
-data = json_graph.node_link_data(G)
-
-# Saved to json file
-with open("concept_graph_full.json", "w", encoding="utf-8") as f:
- json.dump(data, f, indent=4)
-
-print("Full graph saved to concept_graph_full.json")
-
-
-'''
-plt.figure(figsize=(22, 14))
-pos = nx.spring_layout(G, k=0.5, seed=42)
-nx.draw(G, pos, with_labels=True,
- node_color="lightblue", node_size=2500,
- edge_color="gray", arrows=True, width=2, font_size=10)
-plt.title("Concept Graph from Manually Curated Lecture Concepts", fontsize=14)
-plt.axis("off")
-plt.tight_layout()
-plt.show()
-'''
diff --git a/concept_graph.html b/concept_graph.html
deleted file mode 100644
index a9e161654..000000000
--- a/concept_graph.html
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/concept_graph.json b/concept_graph.json
deleted file mode 100644
index 6dea722e7..000000000
--- a/concept_graph.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- { "id": "1", "name": "What is computation?", "prerequisites": [] },
- { "id": "2", "name": "Branching and Iteration", "prerequisites": ["1"] },
- { "id": "3", "name": "String Manipulation, Guess and Check, Approximations, Bisection", "prerequisites": ["2"] },
- { "id": "4", "name": "Decomposition, Abstractions, Functions", "prerequisites": ["3"] },
- { "id": "5", "name": "Tuples, Lists, Aliasing, Mutability, Cloning", "prerequisites": ["4"] },
- { "id": "6", "name": "Recursion, Dictionaries", "prerequisites": ["5"] },
- { "id": "7", "name": "Testing, Debugging, Exceptions, Assertions", "prerequisites": ["6"] },
- { "id": "8", "name": "Object Oriented Programming", "prerequisites": ["7"] },
- { "id": "9", "name": "Python Classes and Inheritance", "prerequisites": ["8"] },
- { "id": "10", "name": "Understanding Program Efficiency, Part 1", "prerequisites": ["9"] },
- { "id": "11", "name": "Understanding Program Efficiency, Part 2", "prerequisites": ["10"] },
- { "id": "12", "name": "Searching and Sorting", "prerequisites": ["11"] }
-]
diff --git a/concept_graph_full.json b/concept_graph_full.json
deleted file mode 100644
index f256d4bc9..000000000
--- a/concept_graph_full.json
+++ /dev/null
@@ -1,338 +0,0 @@
-{
- "directed": true,
- "multigraph": false,
- "graph": {},
- "nodes": [
- {
- "id": "Computation"
- },
- {
- "id": "Algorithms"
- },
- {
- "id": "Problem Solving"
- },
- {
- "id": "Conditionals"
- },
- {
- "id": "Loops"
- },
- {
- "id": "Control Flow"
- },
- {
- "id": "String Manipulation"
- },
- {
- "id": "Guess and Check"
- },
- {
- "id": "Approximation"
- },
- {
- "id": "Bisection Search"
- },
- {
- "id": "Decomposition"
- },
- {
- "id": "Abstraction"
- },
- {
- "id": "Functions"
- },
- {
- "id": "Tuples"
- },
- {
- "id": "Lists"
- },
- {
- "id": "Aliasing"
- },
- {
- "id": "Mutability"
- },
- {
- "id": "Cloning"
- },
- {
- "id": "Recursion"
- },
- {
- "id": "Dictionaries"
- },
- {
- "id": "Testing"
- },
- {
- "id": "Debugging"
- },
- {
- "id": "Exceptions"
- },
- {
- "id": "Assertions"
- },
- {
- "id": "Classes"
- },
- {
- "id": "OOP"
- },
- {
- "id": "Encapsulation"
- },
- {
- "id": "Inheritance"
- },
- {
- "id": "Subclasses"
- },
- {
- "id": "Class Hierarchies"
- },
- {
- "id": "Big-O Notation"
- },
- {
- "id": "Efficiency"
- },
- {
- "id": "Space Complexity"
- },
- {
- "id": "Search Algorithms"
- },
- {
- "id": "Sorting Algorithms"
- }
- ],
- "links": [
- {
- "source": "Computation",
- "target": "Algorithms"
- },
- {
- "source": "Algorithms",
- "target": "Problem Solving"
- },
- {
- "source": "Problem Solving",
- "target": "Conditionals"
- },
- {
- "source": "Problem Solving",
- "target": "Loops"
- },
- {
- "source": "Problem Solving",
- "target": "Control Flow"
- },
- {
- "source": "Conditionals",
- "target": "Loops"
- },
- {
- "source": "Loops",
- "target": "Control Flow"
- },
- {
- "source": "Control Flow",
- "target": "String Manipulation"
- },
- {
- "source": "Control Flow",
- "target": "Guess and Check"
- },
- {
- "source": "Control Flow",
- "target": "Approximation"
- },
- {
- "source": "Control Flow",
- "target": "Bisection Search"
- },
- {
- "source": "String Manipulation",
- "target": "Guess and Check"
- },
- {
- "source": "Guess and Check",
- "target": "Approximation"
- },
- {
- "source": "Approximation",
- "target": "Bisection Search"
- },
- {
- "source": "Bisection Search",
- "target": "Decomposition"
- },
- {
- "source": "Bisection Search",
- "target": "Abstraction"
- },
- {
- "source": "Bisection Search",
- "target": "Functions"
- },
- {
- "source": "Decomposition",
- "target": "Abstraction"
- },
- {
- "source": "Abstraction",
- "target": "Functions"
- },
- {
- "source": "Functions",
- "target": "Tuples"
- },
- {
- "source": "Functions",
- "target": "Lists"
- },
- {
- "source": "Functions",
- "target": "Aliasing"
- },
- {
- "source": "Functions",
- "target": "Mutability"
- },
- {
- "source": "Functions",
- "target": "Cloning"
- },
- {
- "source": "Tuples",
- "target": "Lists"
- },
- {
- "source": "Lists",
- "target": "Aliasing"
- },
- {
- "source": "Aliasing",
- "target": "Mutability"
- },
- {
- "source": "Mutability",
- "target": "Cloning"
- },
- {
- "source": "Cloning",
- "target": "Recursion"
- },
- {
- "source": "Cloning",
- "target": "Dictionaries"
- },
- {
- "source": "Recursion",
- "target": "Dictionaries"
- },
- {
- "source": "Dictionaries",
- "target": "Testing"
- },
- {
- "source": "Dictionaries",
- "target": "Debugging"
- },
- {
- "source": "Dictionaries",
- "target": "Exceptions"
- },
- {
- "source": "Dictionaries",
- "target": "Assertions"
- },
- {
- "source": "Testing",
- "target": "Debugging"
- },
- {
- "source": "Debugging",
- "target": "Exceptions"
- },
- {
- "source": "Exceptions",
- "target": "Assertions"
- },
- {
- "source": "Assertions",
- "target": "Classes"
- },
- {
- "source": "Assertions",
- "target": "OOP"
- },
- {
- "source": "Assertions",
- "target": "Encapsulation"
- },
- {
- "source": "Classes",
- "target": "OOP"
- },
- {
- "source": "OOP",
- "target": "Encapsulation"
- },
- {
- "source": "Encapsulation",
- "target": "Inheritance"
- },
- {
- "source": "Encapsulation",
- "target": "Subclasses"
- },
- {
- "source": "Encapsulation",
- "target": "Class Hierarchies"
- },
- {
- "source": "Inheritance",
- "target": "Subclasses"
- },
- {
- "source": "Subclasses",
- "target": "Class Hierarchies"
- },
- {
- "source": "Class Hierarchies",
- "target": "Big-O Notation"
- },
- {
- "source": "Class Hierarchies",
- "target": "Efficiency"
- },
- {
- "source": "Big-O Notation",
- "target": "Efficiency"
- },
- {
- "source": "Efficiency",
- "target": "Efficiency"
- },
- {
- "source": "Efficiency",
- "target": "Space Complexity"
- },
- {
- "source": "Space Complexity",
- "target": "Search Algorithms"
- },
- {
- "source": "Space Complexity",
- "target": "Sorting Algorithms"
- },
- {
- "source": "Search Algorithms",
- "target": "Sorting Algorithms"
- }
- ]
-}
\ No newline at end of file
diff --git a/cps b/cps
deleted file mode 160000
index 2d768b1cd..000000000
--- a/cps
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2d768b1cd5a5a8bd133ad47fd1b3abf48d2f041d
diff --git a/fetch_lectures.py b/fetch_lectures.py
deleted file mode 100644
index 742c02125..000000000
--- a/fetch_lectures.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import requests
-import time
-from bs4 import BeautifulSoup
-from bs4.element import Tag
-import json
-
-url = "https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/pages/lecture-slides-code/"
-
-session = requests.Session()
-time.sleep(2) # Sleep to avoid overwhelming the server
-r = session.get(url)
-
-with open("lecture_slides_code.html", "w", encoding='utf-8') as f:
- f.write(r.text)
-print("HTML content retrieved and saved to lecture_slides_code.html")
-
-with open("lecture_slides_code.html", "r", encoding='utf-8') as f:
- html_content = f.read()
-
-soup = BeautifulSoup(html_content, 'html.parser')
-rows = soup.find_all("tr")
-
-lecture_titles = []
-
-for row in rows:
- if isinstance(row, Tag):
- cols = row.find_all("td")
- if len(cols) >= 2:
- title = cols[1].get_text(strip=True)
- if title:
- lecture_titles.append(title)
-
-# Save lecture titles to a text file (optional)
-with open("lecture_titles.txt", "w", encoding='utf-8') as f:
- for title in lecture_titles:
- f.write(title + "\n")
-
-print(f"Extracted {len(lecture_titles)} lecture titles and saved to lecture_titles.txt")
-
-# Save lecture titles to JSON file
-with open("lecture_titles.json", "w", encoding='utf-8') as f_json:
- json.dump(lecture_titles, f_json, ensure_ascii=False, indent=2)
-
-print(f"Saved {len(lecture_titles)} lecture titles to lecture_titles.json")
diff --git a/index.html b/index.html
deleted file mode 100644
index 039e57648..000000000
--- a/index.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
- MIT OCW Python Course Graph
-
-
-
-
- MIT OCW Python Course Graph
-
-
-
-
-
diff --git a/learner_profiles.json b/learner_profiles.json
deleted file mode 100644
index 63f1f1f88..000000000
--- a/learner_profiles.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "learner_id": "L001",
- "mastered_concepts": ["Computation", "Algorithms"],
- "weak_concepts": ["Problem Solving"]
- },
- {
- "learner_id": "L002",
- "mastered_concepts": ["Computation"],
- "weak_concepts": []
- }
-]
\ No newline at end of file
diff --git a/lecture_prerequisites_graph (1).png b/lecture_prerequisites_graph (1).png
deleted file mode 100644
index b134c4ff9..000000000
Binary files a/lecture_prerequisites_graph (1).png and /dev/null differ
diff --git a/lecture_slides_code.html b/lecture_slides_code.html
deleted file mode 100644
index 6df87b1a0..000000000
--- a/lecture_slides_code.html
+++ /dev/null
@@ -1,2695 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lecture Slides and Code | Introduction to Computer Science and Programming in Python | Electrical Engineering and Computer Science | MIT OpenCourseWare
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6.0001 | Fall 2016 | Undergraduate
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Menu
-
-
-
-
-
-
-
-
-
- More Info
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Syllabus
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Readings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The slides and code from each lecture are available below.
-
-
-
-
-
-
-
-
-SESΓΒ #
-
-
-
-
-TOPICS
-
-
-
-
-LECTURE SLIDES
-
-
-
-
-LECTURE CODES
-
-
-
-
-
-
-
-
-
-
-1
-
-
-
-
-What is computation?
-
-
-
-
-Slides for Lecture 1 (PDF)
-
-
-
-
-Code for Lecture 1 (PY)
-
-
-
-
-
-
-
-
-2
-
-
-
-
-Branching and Iteration
-
-
-
-
-Slides for Lecture 2 (PDF)
-
-
-
-
-Code for Lecture 2 (PY)
-
-
-
-
-
-
-
-
-3
-
-
-
-
-String Manipulation, Guess and Check, Approximations, Bisection
-
-
-
-
-Slides for Lecture 3 (PDF)
-
-
-
-
-Code for Lecture 3 (PY)
-
-
-
-
-
-
-
-
-4
-
-
-
-
-Decomposition, Abstractions, Functions
-
-
-
-
-Slides for Lecture 4 (PDF 1.1MB)
-
-
-
-
-Code for Lecture 4 (PY)
-
-
-
-
-
-
-
-
-5
-
-
-
-
-Tuples, Lists, Aliasing, Mutability, Cloning
-
-
-
-
-Slides for Lecture 5 (PDF)
-
-
-
-
-Code for Lecture 5 (PY)
-
-
-
-
-
-
-
-
-6
-
-
-
-
-Recursion, Dictionaries
-
-
-
-
-Slides for Lecture 6 (PDF - 1.3MB)
-
-
-
-
-Code for Lecture 6 (PY)
-
-
-
-
-
-
-
-
-7
-
-
-
-
-Testing, Debugging, Exceptions, Assertions
-
-
-
-
-Slides for Lecture 7 (PDF)
-
-
-
-
-Code for Lecture 7 (PY)
-
-
-
-
-
-
-
-
-8
-
-
-
-
-Object Oriented Programming
-
-
-
-
-Slides for Lecture 8 (PDF)
-
-
-
-
-Code for Lecture 8 (PY)
-
-
-
-
-
-
-
-
-9
-
-
-
-
-Python Classes and Inheritance
-
-
-
-
-Slides for Lecture 9 (PDF - 1.6MB)
-
-
-
-
-Code for Lecture 9 (PY)
-
-
-
-
-
-
-
-
-10
-
-
-
-
-Understanding Program Efficiency, Part 1
-
-
-
-
-Slides for Lecture 10 (PDF)
-
-
-
-
-Code for Lecture 10 (PY)
-
-
-
-
-
-
-
-
-11
-
-
-
-
-Understanding Program Efficiency, Part 2
-
-
-
-
-Slides for Lecture 11 (PDF)
-
-
-
-
-Code for Lecture 11 (PY)
-
-
-
-
-
-
-
-
-12
-
-
-
-
-Searching and Sorting
-
-
-
-
-Slides for Lecture 12 (PDF - 2.4MB)
-
-
-
-
-Code for Lecture 12 (PY)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Course Info
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- As Taught In
-
-
- Fall
-
- 2016
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Topics
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Learning Resource Types
-
-
-
-
-
-
-
-
-
- assignment
- Problem Sets
-
-
-
-
-
-
-
-
-
-
- notes
- Lecture Notes
-
-
-
-
-
-
-
-
-
-
- theaters
- Lecture Videos
-
-
-
-
-
-
-
-
-
-
- assignment_turned_in
- Programming Assignments with Examples
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please be advised that external sites may have terms and conditions,
- including license rights, that differ from ours. MIT OCW is not responsible
- for any content on third party sites, nor does a link suggest an endorsement
- of those sites and/or their content.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lecture_titles.json b/lecture_titles.json
deleted file mode 100644
index 0944128ea..000000000
--- a/lecture_titles.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- "What is computation?",
- "Branching and Iteration",
- "String Manipulation, Guess and Check, Approximations, Bisection",
- "Decomposition, Abstractions, Functions",
- "Tuples, Lists, Aliasing, Mutability, Cloning",
- "Recursion, Dictionaries",
- "Testing, Debugging, Exceptions, Assertions",
- "Object Oriented Programming",
- "Python Classes and Inheritance",
- "Understanding Program Efficiency, Part 1",
- "Understanding Program Efficiency, Part 2",
- "Searching and Sorting"
-]
\ No newline at end of file
diff --git a/lecture_titles.txt b/lecture_titles.txt
deleted file mode 100644
index 68f640f73..000000000
--- a/lecture_titles.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-What is computation?
-Branching and Iteration
-String Manipulation, Guess and Check, Approximations, Bisection
-Decomposition, Abstractions, Functions
-Tuples, Lists, Aliasing, Mutability, Cloning
-Recursion, Dictionaries
-Testing, Debugging, Exceptions, Assertions
-Object Oriented Programming
-Python Classes and Inheritance
-Understanding Program Efficiency, Part 1
-Understanding Program Efficiency, Part 2
-Searching and Sorting
diff --git a/lectures.json b/lectures.json
deleted file mode 100644
index dd78a2e78..000000000
--- a/lectures.json
+++ /dev/null
@@ -1,8 +0,0 @@
-[
- { "id": 1, "title": "Introduction to Python" },
- { "id": 2, "title": "Data Types and Variables" },
- { "id": 3, "title": "Control Structures" },
- { "id": 4, "title": "Functions" },
- { "id": 5, "title": "Modules and Packages" },
- { "id": 6, "title": "Object-Oriented Programming" }
-]
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index ddedb5691..000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,1224 +0,0 @@
-{
- "name": "learning_path",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "learning_path",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "bcryptjs": "^3.0.2",
- "cors": "^2.8.5",
- "express": "^5.1.0",
- "jsonwebtoken": "^9.0.2",
- "mongodb": "^6.17.0",
- "mongoose": "^8.15.1"
- }
- },
- "node_modules/@mongodb-js/saslprep": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz",
- "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==",
- "license": "MIT",
- "dependencies": {
- "sparse-bitfield": "^3.0.3"
- }
- },
- "node_modules/@types/webidl-conversions": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
- "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
- "license": "MIT"
- },
- "node_modules/@types/whatwg-url": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
- "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
- "license": "MIT",
- "dependencies": {
- "@types/webidl-conversions": "*"
- }
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/bcryptjs": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
- "integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
- "license": "BSD-3-Clause",
- "bin": {
- "bcrypt": "bin/bcrypt"
- }
- },
- "node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/bson": {
- "version": "6.10.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
- "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.20.1"
- }
- },
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/debug": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
- "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http-errors/node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
- },
- "node_modules/jsonwebtoken": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
- "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
- "license": "MIT",
- "dependencies": {
- "jws": "^3.2.2",
- "lodash.includes": "^4.3.0",
- "lodash.isboolean": "^3.0.3",
- "lodash.isinteger": "^4.0.4",
- "lodash.isnumber": "^3.0.3",
- "lodash.isplainobject": "^4.0.6",
- "lodash.isstring": "^4.0.1",
- "lodash.once": "^4.0.0",
- "ms": "^2.1.1",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- }
- },
- "node_modules/jwa": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
- "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
- "license": "MIT",
- "dependencies": {
- "buffer-equal-constant-time": "^1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "license": "MIT",
- "dependencies": {
- "jwa": "^1.4.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/kareem": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
- "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/lodash.includes": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
- "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
- "license": "MIT"
- },
- "node_modules/lodash.isboolean": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
- "license": "MIT"
- },
- "node_modules/lodash.isinteger": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
- "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
- "license": "MIT"
- },
- "node_modules/lodash.isnumber": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
- "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
- "license": "MIT"
- },
- "node_modules/lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "license": "MIT"
- },
- "node_modules/lodash.isstring": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
- "license": "MIT"
- },
- "node_modules/lodash.once": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
- "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
- "license": "MIT"
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "license": "MIT"
- },
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mongodb": {
- "version": "6.17.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.17.0.tgz",
- "integrity": "sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.4",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
- }
- },
- "node_modules/mongodb-connection-string-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
- "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/whatwg-url": "^11.0.2",
- "whatwg-url": "^14.1.0 || ^13.0.0"
- }
- },
- "node_modules/mongoose": {
- "version": "8.15.1",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.15.1.tgz",
- "integrity": "sha512-RhQ4DzmBi5BNGcS0w4u1vdMRIKcteXTCNzDt1j7XRcdWYBz1MjMjulBhPaeC5jBCHOD1yinuOFTTSOWLLGexWw==",
- "license": "MIT",
- "dependencies": {
- "bson": "^6.10.3",
- "kareem": "2.6.3",
- "mongodb": "~6.16.0",
- "mpath": "0.9.0",
- "mquery": "5.0.0",
- "ms": "2.1.3",
- "sift": "17.1.3"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mongoose"
- }
- },
- "node_modules/mongoose/node_modules/mongodb": {
- "version": "6.16.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.16.0.tgz",
- "integrity": "sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.3",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
- }
- },
- "node_modules/mpath": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
- "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/mquery": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
- "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
- "license": "MIT",
- "dependencies": {
- "debug": "4.x"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-to-regexp": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
- "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
- "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/sift": {
- "version": "17.1.3",
- "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
- "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
- "license": "MIT"
- },
- "node_modules/sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
- "license": "MIT",
- "dependencies": {
- "memory-pager": "^1.0.2"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/type-is": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- }
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index 1ee29c497..000000000
--- a/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "learning_path",
- "version": "1.0.0",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "description": "",
- "dependencies": {
- "bcryptjs": "^3.0.2",
- "cors": "^2.8.5",
- "express": "^5.1.0",
- "jsonwebtoken": "^9.0.2",
- "mongodb": "^6.17.0",
- "mongoose": "^8.15.1"
- }
-}
diff --git a/project-alpha/.gitignore b/project-alpha/.gitignore
deleted file mode 100644
index 3168325eb..000000000
--- a/project-alpha/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-node_modules
-.env
-dist
-.DS_Store
\ No newline at end of file
diff --git a/project-alpha/LICENSE b/project-alpha/LICENSE
deleted file mode 100644
index 1a15e1b51..000000000
--- a/project-alpha/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2025 sivasai
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/project-alpha/README.md b/project-alpha/README.md
deleted file mode 100644
index e63ee9a43..000000000
--- a/project-alpha/README.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Personalized Learning Path Recommendation
-
-An experimental AI-powered educational tool that recommends personalized learning paths based on a userβs target topic. The system dynamically constructs a prerequisite concept graph to identify foundational knowledge, and uses GPT-based analysis to generate diagnostic assessments β ensuring learners build a strong conceptual base before progressing.
-
-This project is actively being developed using the MERN stack, with plans to integrate advanced agentic reasoning and adaptive feedback for scalable and personalized learning support.
-
-
-
----
-
-## Status
-
-> This project is currently in early development. Features and APIs are subject to frequent changes.
-
----
-
-## System Workflow (4 Stages)
-
-### Stage 1: Prerequisite Graph Construction
-
-- Accepts any user-given topic (e.g., "Machine Learning").
-- Uses GPT-4o to generate 5β7 relevant prerequisite concepts
-- Visualizes them as a Directed Acyclic Graph (DAG).
-
-### Stage 2: MCQ Exam Generator
-
-- Automatically generates diagnostic multiple-choice questions based on each prerequisite concept.
-- Questions are AI-generated and domain-aware.
-
-### Stage 3: Result Display and Analysis
-- Evaluates user responses to identify strengths and knowledge gaps.
-- Provides clear, structured feedback
-
-### Stage 4: Personalized Learning Path Recommendation
-- Constructs a custom learning path based on analysis of prerequisite performance
-- Highlights weak areas and recommends learning order
-
----
-
-## How to Run the Project
-
-### 1. Clone the Repository
-
-### 2. Add Your OpenRouter API Key
-
-* Create a `.env` file in the **`backend/`** directory.
-* Add the following lines to the `.env` file:
-
-```env
-OPENROUTER_API_KEY=your_openrouter_key_here
-MONGO_URI=mongodb://localhost:27017/cps-prerequisites
-```
-
-> Make sure the `.env` file is located inside the `backend/` folder.
-
----
-
-### 3. Start the Application
-
-#### In Terminal 1 (Frontend)
-
-```bash
-cd frontend
-npm install
-npm start
-```
-
-This will start the frontend on http://localhost:5173 (Vite default)
-
-#### In Terminal 2 (Backend)
-
-```bash
-cd backend
-npm install
-npm start
-```
-
----
-
-## What Happens Now
-
-* Enter a concept or topic in the input field (e.g., "Machine Learning").
-* The system will:
- * Call OpenRouter (GPT-4o) to generate 5β7 prerequisite concepts.
- * Save the topic and prerequisites in MongoDB.
- * Display them as a bullet list and a directed graph (DAG) on the frontend.
-
----
-
-## Tech Stack
-
-* **Frontend**: React (TypeScript)
-* **Backend**: Node.js + Express
-* **Database**: MongoDB
-* **AI/LLM**: GPT-4o via OpenRouter
-* **Graph Rendering**: vis-network
-* **Environment Management**: dotenv
-
-
diff --git a/project-alpha/backend/package-lock.json b/project-alpha/backend/package-lock.json
deleted file mode 100644
index f0afbfb8b..000000000
--- a/project-alpha/backend/package-lock.json
+++ /dev/null
@@ -1,2066 +0,0 @@
-{
- "name": "backend",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "backend",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "axios": "^1.9.0",
- "cors": "^2.8.5",
- "dotenv": "^16.5.0",
- "express": "^5.1.0",
- "mongoose": "^8.15.1"
- },
- "devDependencies": {
- "@types/cors": "^2.8.19",
- "@types/dotenv": "^6.1.1",
- "@types/express": "^5.0.3",
- "@types/node": "^24.0.0",
- "ts-node-dev": "^2.0.0",
- "typescript": "^5.8.3"
- }
- },
- "node_modules/@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@mongodb-js/saslprep": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz",
- "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==",
- "license": "MIT",
- "dependencies": {
- "sparse-bitfield": "^3.0.3"
- }
- },
- "node_modules/@tsconfig/node10": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
- "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node16": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
- "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/body-parser": {
- "version": "1.19.6",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
- "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/connect": {
- "version": "3.4.38",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
- "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/cors": {
- "version": "2.8.19",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
- "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/dotenv": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
- "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/express": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
- "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^5.0.0",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/express-serve-static-core": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
- "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/http-errors": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
- "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/mime": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
- "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "24.0.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.1.tgz",
- "integrity": "sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.8.0"
- }
- },
- "node_modules/@types/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/range-parser": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/send": {
- "version": "0.17.5",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
- "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/mime": "^1",
- "@types/node": "*"
- }
- },
- "node_modules/@types/serve-static": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
- "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/http-errors": "*",
- "@types/node": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/strip-json-comments": {
- "version": "0.0.30",
- "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
- "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/webidl-conversions": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
- "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
- "license": "MIT"
- },
- "node_modules/@types/whatwg-url": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
- "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
- "license": "MIT",
- "dependencies": {
- "@types/webidl-conversions": "*"
- }
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
- },
- "node_modules/axios": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
- "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/bson": {
- "version": "6.10.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
- "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.20.1"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
- "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/dotenv": {
- "version": "16.5.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
- "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/dynamic-dedupe": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
- "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "xtend": "^4.0.0"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/follow-redirects": {
- "version": "1.15.9",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
- "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/form-data": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
- "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.2",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/form-data/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/form-data/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http-errors/node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
- },
- "node_modules/kareem": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
- "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "license": "MIT"
- },
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/mongodb": {
- "version": "6.16.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.16.0.tgz",
- "integrity": "sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.3",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
- }
- },
- "node_modules/mongodb-connection-string-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
- "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/whatwg-url": "^11.0.2",
- "whatwg-url": "^14.1.0 || ^13.0.0"
- }
- },
- "node_modules/mongoose": {
- "version": "8.15.1",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.15.1.tgz",
- "integrity": "sha512-RhQ4DzmBi5BNGcS0w4u1vdMRIKcteXTCNzDt1j7XRcdWYBz1MjMjulBhPaeC5jBCHOD1yinuOFTTSOWLLGexWw==",
- "license": "MIT",
- "dependencies": {
- "bson": "^6.10.3",
- "kareem": "2.6.3",
- "mongodb": "~6.16.0",
- "mpath": "0.9.0",
- "mquery": "5.0.0",
- "ms": "2.1.3",
- "sift": "17.1.3"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mongoose"
- }
- },
- "node_modules/mpath": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
- "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/mquery": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
- "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
- "license": "MIT",
- "dependencies": {
- "debug": "4.x"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-to-regexp": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
- "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/sift": {
- "version": "17.1.3",
- "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
- "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
- "license": "MIT"
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
- "license": "MIT",
- "dependencies": {
- "memory-pager": "^1.0.2"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/tree-kill": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
- "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "tree-kill": "cli.js"
- }
- },
- "node_modules/ts-node": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
- "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- },
- "bin": {
- "ts-node": "dist/bin.js",
- "ts-node-cwd": "dist/bin-cwd.js",
- "ts-node-esm": "dist/bin-esm.js",
- "ts-node-script": "dist/bin-script.js",
- "ts-node-transpile-only": "dist/bin-transpile.js",
- "ts-script": "dist/bin-script-deprecated.js"
- },
- "peerDependencies": {
- "@swc/core": ">=1.2.50",
- "@swc/wasm": ">=1.2.50",
- "@types/node": "*",
- "typescript": ">=2.7"
- },
- "peerDependenciesMeta": {
- "@swc/core": {
- "optional": true
- },
- "@swc/wasm": {
- "optional": true
- }
- }
- },
- "node_modules/ts-node-dev": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz",
- "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^3.5.1",
- "dynamic-dedupe": "^0.3.0",
- "minimist": "^1.2.6",
- "mkdirp": "^1.0.4",
- "resolve": "^1.0.0",
- "rimraf": "^2.6.1",
- "source-map-support": "^0.5.12",
- "tree-kill": "^1.2.2",
- "ts-node": "^10.4.0",
- "tsconfig": "^7.0.0"
- },
- "bin": {
- "ts-node-dev": "lib/bin.js",
- "tsnd": "lib/bin.js"
- },
- "engines": {
- "node": ">=0.8.0"
- },
- "peerDependencies": {
- "node-notifier": "*",
- "typescript": "*"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/tsconfig": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
- "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/strip-bom": "^3.0.0",
- "@types/strip-json-comments": "0.0.30",
- "strip-bom": "^3.0.0",
- "strip-json-comments": "^2.0.0"
- }
- },
- "node_modules/type-is": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typescript": {
- "version": "5.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
- "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
- "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4"
- }
- },
- "node_modules/yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- }
- }
-}
diff --git a/project-alpha/backend/package.json b/project-alpha/backend/package.json
deleted file mode 100644
index 221318db6..000000000
--- a/project-alpha/backend/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "backend",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "ts-node-dev src/index.ts",
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "type": "commonjs",
- "dependencies": {
- "axios": "^1.9.0",
- "cors": "^2.8.5",
- "dotenv": "^16.5.0",
- "express": "^5.1.0",
- "mongoose": "^8.15.1"
- },
- "devDependencies": {
- "@types/cors": "^2.8.19",
- "@types/dotenv": "^6.1.1",
- "@types/express": "^5.0.3",
- "@types/node": "^24.0.0",
- "ts-node-dev": "^2.0.0",
- "typescript": "^5.8.3"
- }
-}
\ No newline at end of file
diff --git a/project-alpha/backend/src/index.ts b/project-alpha/backend/src/index.ts
deleted file mode 100644
index c927b89f0..000000000
--- a/project-alpha/backend/src/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import express from 'express';
-import mongoose from 'mongoose';
-import cors from 'cors';
-import dotenv from 'dotenv';
-import prereqRoutes from './routes/prerequisites';
-
-dotenv.config(); // Load .env
-
-const app = express();
-app.use(cors());
-app.use(express.json());
-
-app.use('/api/prerequisites', prereqRoutes);
-
-mongoose.connect(process.env.MONGO_URI!)
- .then(() => console.log('MongoDB connected'))
- .catch(err => console.error(err));
-
-const PORT = process.env.PORT || 5000;
-app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
\ No newline at end of file
diff --git a/project-alpha/backend/src/models/Prereq.ts b/project-alpha/backend/src/models/Prereq.ts
deleted file mode 100644
index 65237acf9..000000000
--- a/project-alpha/backend/src/models/Prereq.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import mongoose from 'mongoose';
-
-const prereqSchema = new mongoose.Schema({
- topic: { type: String, required: true },
- prerequisites: { type: [String], required: true },
-});
-
-export default mongoose.model('Prereq', prereqSchema);
\ No newline at end of file
diff --git a/project-alpha/backend/src/routes/prerequisites.ts b/project-alpha/backend/src/routes/prerequisites.ts
deleted file mode 100644
index af99d5fd7..000000000
--- a/project-alpha/backend/src/routes/prerequisites.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Router, Request, Response } from 'express';
-import Prereq from '../models/Prereq';
-import { generatePrerequisites } from '../services/prereqGenerator';
-
-const router = Router();
-
-router.post('/', async (req: Request, res: Response) => {
- const { topic } = req.body;
- try {
- const prereqs = await generatePrerequisites(topic);
- const newEntry = new Prereq({ topic, prerequisites: prereqs });
- await newEntry.save();
- res.json({ topic, prerequisites: prereqs });
- } catch (err) {
- res.status(500).json({ error: 'Error generating prerequisites' });
- }
-});
-
-export default router;
\ No newline at end of file
diff --git a/project-alpha/backend/src/services/prereqGenerator.ts b/project-alpha/backend/src/services/prereqGenerator.ts
deleted file mode 100644
index 31c70fd40..000000000
--- a/project-alpha/backend/src/services/prereqGenerator.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import axios from 'axios';
-
-export async function generatePrerequisites(topic: string): Promise {
- try {
- console.log('β³ Asking GPT-4o via OpenRouter for topic:', topic);
-
- const response = await axios.post(
- 'https://openrouter.ai/api/v1/chat/completions',
- {
- model: 'openai/gpt-4o',
- max_tokens: 200, // β
Limit token usage to fit free plan
- messages: [
- {
- role: 'user',
- content: `List 5 to 7 prerequisite concepts needed to understand "${topic}" in computer science. Only return the concepts as a plain numbered list.`,
- },
- ],
- },
- {
- headers: {
- Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
- 'Content-Type': 'application/json',
- },
- }
- );
-
- const content: string = response.data.choices[0]?.message?.content ?? '';
- console.log('β
GPT Response:', content);
-
- const list = content
- .split('\n')
- .map((line: string) => line.replace(/^\d+\.?\s*/, '').trim())
- .filter(Boolean);
-
- return list.length > 0 ? list : ['β οΈ Could not generate prerequisites. Try another topic.'];
- } catch (error: any) {
- console.error('β GPT API error:\n', error?.response?.data || error.message);
- return ['β οΈ Unable to generate prerequisites. Try another topic.'];
- }
-}
\ No newline at end of file
diff --git a/project-alpha/backend/tsconfig.json b/project-alpha/backend/tsconfig.json
deleted file mode 100644
index 570128d5f..000000000
--- a/project-alpha/backend/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "target": "es6",
- "module": "commonjs",
- "rootDir": "./src",
- "outDir": "./dist",
- "esModuleInterop": true,
- "strict": true,
- "skipLibCheck": true
- }
-}
\ No newline at end of file
diff --git a/project-alpha/frontend/index.html b/project-alpha/frontend/index.html
deleted file mode 100644
index e4b78eae1..000000000
--- a/project-alpha/frontend/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- Vite + React + TS
-
-
-
-
-
-
diff --git a/project-alpha/frontend/src/App.css b/project-alpha/frontend/src/App.css
deleted file mode 100644
index b9d355df2..000000000
--- a/project-alpha/frontend/src/App.css
+++ /dev/null
@@ -1,42 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
diff --git a/project-alpha/frontend/src/App.tsx b/project-alpha/frontend/src/App.tsx
deleted file mode 100644
index 2618f3ea6..000000000
--- a/project-alpha/frontend/src/App.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import { useState } from 'react';
-import axios from 'axios';
-import Graph from './components/Graph';
-//import PrereqList from './components/PrereqList';
-
-type PrereqData = {
- topic: string;
- prerequisites: string[];
-};
-
-function App() {
- const [topic, setTopic] = useState('');
- const [data, setData] = useState(null);
-
- const handleSubmit = async () => {
- if (!topic.trim()) return;
-
- try {
- const res = await axios.post('http://localhost:5000/api/prerequisites', { topic });
- setData(res.data);
- } catch (err) {
- console.error('Error fetching prerequisites', err);
- }
- };
-
- return (
-
-
- {/* LEFT SIDE */}
-
-
- Concept Prerequisite Graph
-
-
-
- setTopic(e.target.value)}
- placeholder="Enter a topic (e.g. Machine Learning)"
- style={{
- padding: '12px',
- fontSize: '16px',
- flexGrow: 1,
- border: '1px solid #ccc',
- borderRadius: '6px',
- }}
- />
-
- Generate
-
-
-
- {data && (
- <>
-
Prerequisite List
-
- {data.prerequisites.map((item, i) => (
-
- {item}
-
- ))}
-
- >
- )}
-
-
- {/* RIGHT SIDE */}
-
- {data && (
- <>
-
- Graph for {data.topic}
-
-
- >
- )}
-
-
-
- );
-}
-
-export default App;
\ No newline at end of file
diff --git a/project-alpha/frontend/src/components/Graph.tsx b/project-alpha/frontend/src/components/Graph.tsx
deleted file mode 100644
index 82f9f56b7..000000000
--- a/project-alpha/frontend/src/components/Graph.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import { useEffect, useRef } from 'react';
-import { DataSet, Network } from 'vis-network/standalone';
-import type { Node, Edge } from 'vis-network';
-
-type GraphProps = {
- topic: string;
- prerequisites: string[];
-};
-
-const Graph = ({ topic, prerequisites }: GraphProps) => {
- const containerRef = useRef(null);
-
- useEffect(() => {
- if (!containerRef.current) return;
-
- const nodes: Node[] = [
- { id: 'Start', label: 'Start', color: '#90caf9', level: 0 },
- ...prerequisites.map((p, i) => ({
- id: p,
- label: p,
- color: '#a5d6a7',
- level: i + 1,
- })),
- { id: topic, label: topic, color: '#ffab91', level: prerequisites.length + 1 },
- ];
-
- const edges: Edge[] = [];
-
- // Connect: Start β prereq1
- if (prerequisites.length > 0) {
- edges.push({ from: 'Start', to: prerequisites[0], arrows: 'to' });
-
- // Chain: prereq1 β prereq2 β ...
- for (let i = 0; i < prerequisites.length - 1; i++) {
- edges.push({ from: prerequisites[i], to: prerequisites[i + 1], arrows: 'to' });
- }
-
- // Final prereq β Topic
- edges.push({ from: prerequisites[prerequisites.length - 1], to: topic, arrows: 'to' });
- } else {
- edges.push({ from: 'Start', to: topic, arrows: 'to' });
- }
-
- const data = {
- nodes: new DataSet(nodes),
- edges: new DataSet(edges),
- };
-
- const options = {
- layout: {
- hierarchical: {
- enabled: true,
- levelSeparation: 150,
- direction: 'UD', // Up to Down
- sortMethod: 'directed',
- },
- },
- physics: {
- enabled: false,
- },
- edges: {
- smooth: true,
- arrows: {
- to: { enabled: true, scaleFactor: 1 },
- },
- },
- nodes: {
- shape: 'box',
- font: {
- face: 'Arial',
- size: 14,
- },
- margin: {
- top: 10,
- bottom: 10,
- left: 10,
- right: 10,
- },
- },
- };
-
- new Network(containerRef.current, data, options);
- }, [topic, prerequisites]);
-
- return (
-
- );
-};
-
-export default Graph;
\ No newline at end of file
diff --git a/project-alpha/frontend/src/components/PrereqList.tsx b/project-alpha/frontend/src/components/PrereqList.tsx
deleted file mode 100644
index 7b28f59ff..000000000
--- a/project-alpha/frontend/src/components/PrereqList.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-type Props = {
- list: string[];
-};
-
-const PrereqList: React.FC = ({ list }) => (
-
-
Prerequisite List
-
- {list.map((item, index) => (
- β’ {item}
- ))}
-
-
-);
-
-export default PrereqList;
\ No newline at end of file
diff --git a/project-alpha/frontend/src/index.css b/project-alpha/frontend/src/index.css
deleted file mode 100644
index 08a3ac9e1..000000000
--- a/project-alpha/frontend/src/index.css
+++ /dev/null
@@ -1,68 +0,0 @@
-:root {
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/project-lambda/README.md b/project-lambda/README.md
deleted file mode 100644
index a301e6fb4..000000000
--- a/project-lambda/README.md
+++ /dev/null
@@ -1,47 +0,0 @@
-EduVLM-Bench: A Multimodal Benchmark for Educational Concept Learning
-π― Project Overview
-EduVLM-Bench is a comprehensive benchmark designed to evaluate Vision-Language Models (VLMs) on educational concept prerequisite identification. The core problem we're addressing is: When a student fails to answer a question correctly, how can we identify the missing prerequisites that will help bridge the gap from confusion to correct understanding?
-Key Innovation
-Rather than just evaluating whether models can solve problems, we focus on diagnostic capability - can models identify what knowledge is missing when learning breaks down?
-π Research Vision
-This project aims to create a framework that can:
-
-Identify Missing Prerequisites: Given a student's wrong answer, pinpoint specific knowledge gaps
-Generate Learning Paths: Provide structured pathways from current understanding to mastery
-Reduce Annotation Burden: Use AI-generated concept taxonomies to streamline human annotation
-Benchmark VLM Performance: Evaluate models across different scales (2B, 4B, 7B) and architectures
-
-π Current Progress
-β
Phase 1: Concept Taxonomy Building (IN PROGRESS)
-We've successfully extracted prerequisite concepts from the first 200 questions of GSM-8K using Gemini 1.5 Flash.
-Technical Implementation
-python# Core extraction pipeline using Gemini API
-@retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=2))
-def get_prerequisites_with_retry(prompt):
- response = model.generate_content(prompt)
- return response.text.strip()
-Current Statistics
-
-Dataset: GSM-8K first 200 questions
-Model Used: Gemini 1.5 Flash
-Output: Comprehensive CSV of unique mathematical concepts
-Processing: 200/200 questions completed
-Concepts Identified: ~[X unique concepts] (extracted and sorted)
-
-Sample Concepts Extracted
-Addition
-Addition And Subtraction Of Integers
-Addition And Subtraction Of Time
-Times As Old As
-Twice As Old As
-π Next Steps: Phase 2 Error-Prerequisite Mapping
-Current Task: Generate wrong answers with targeted prerequisite gaps using Gemma-3-4B
-Planned Approach:
-
-Question-by-Question Mapping: Create specific prerequisite mappings for each problem
-Controlled Error Generation: Use targeted prompting to generate realistic wrong answers
-Missing Concept Injection: Remove specific prerequisites to create authentic confusion
-
-Model Setup:
-pythonimport lmstudio as lms
-model = lms.llm('gemma-3-4b-it')
diff --git a/project-lambda/error-generation.ipynb b/project-lambda/error-generation.ipynb
deleted file mode 100644
index 1b978342f..000000000
--- a/project-lambda/error-generation.ipynb
+++ /dev/null
@@ -1,391 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "950ea242",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "text-embedding-nomic-embed-text-v1.5\n",
- "internvl3-8b\n",
- "smolvlm2-2.2b-instruct\n",
- "irix-12b-model_stock\n",
- "deepseek-r1-0528-qwen3-8b\n",
- "qwen2.5-vl-32b-instruct\n",
- "qwen2.5-vl-7b-instruct\n",
- "gemma-3-4b-it\n",
- "qwen2-vl-2b-instruct\n",
- "granite-vision-3.2-2b\n",
- "smolvlm2-500m-video-instruct\n",
- "gemma-3-27b-it-qat\n",
- "gemma-3-12b-it-qat\n"
- ]
- }
- ],
- "source": [
- "import lmstudio as lms\n",
- "\n",
- "downloaded = lms.list_downloaded_models()\n",
- "llm_only = lms.list_downloaded_models(\"llm\")\n",
- "embedding_only = lms.list_downloaded_models(\"embedding\")\n",
- "\n",
- "for model in downloaded:\n",
- " print(model.model_key)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "6da3875a",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Okay, let's tackle this big one β the meaning of life. The short answer is: **there isnβt a single, universally agreed-upon answer.** It's arguably *the* most pondered question in human history, and that's because it's deeply personal and philosophical. \n",
- "\n",
- "Here's a breakdown of different perspectives, grouped into categories:\n",
- "\n",
- "**1. Philosophical Perspectives:**\n",
- "\n",
- "* **Nihilism:** This view suggests life is inherently meaningless. Thereβs no objective purpose or value. It can be bleak, but some find freedom in accepting this lack of inherent meaning and creating their own.\n",
- "* **Existentialism:** This philosophy argues that existence precedes essence. We are born into the world without a predetermined purpose. *We* create our own meaning through our choices and actions. Key figures include Sartre and Camus. It emphasizes responsibility β we're responsible for defining ourselves.\n",
- "* **Absurdism:** Closely related to existentialism, absurdism recognizes the conflict between humanityβs innate desire for meaning and the meaningless universe. It suggests embracing this absurdity rather than trying to resolve it. (Camus is a key figure here).\n",
- "* **Hedonism:** The pursuit of pleasure and avoidance of pain is the primary goal and source of meaning. \n",
- "* **Utilitarianism:** Meaning comes from maximizing happiness and well-being for the greatest number of people. Actions are judged by their consequences.\n",
- "* **Stoicism:** Finding meaning through virtue, reason, and acceptance of what we cannot control. Focus on inner peace and living in accordance with nature.\n",
- "\n",
- "\n",
- "**2. Religious & Spiritual Perspectives:**\n",
- "\n",
- "* **Theism (Various Religions):** Most religions offer answers centered around a divine being or higher power. Meaning is often found in serving God, following religious teachings, seeking salvation, and connecting with the divine. Specific meanings vary greatly between faiths (Christianity, Islam, Judaism, Hinduism, Buddhism, etc.).\n",
- "* **Buddhism:** The goal is to escape suffering through enlightenment and achieving Nirvana β a state of liberation from the cycle of rebirth. Meaning comes from cultivating compassion, wisdom, and mindfulness.\n",
- "* **Hinduism:** Meaning is found in fulfilling one's dharma (duty), pursuing karma (actions leading to consequences), and ultimately attaining moksha (liberation) from the cycle of reincarnation.\n",
- "\n",
- "**3. Psychological & Humanistic Perspectives:**\n",
- "\n",
- "* **Viktor Franklβs Logotherapy:** Frankl, a Holocaust survivor, argued that the primary human drive is not pleasure or power, but *meaning*. He believed meaning can be found in:\n",
- " * **Creating something (doing)** β contributing to the world through work, art, or acts of service.\n",
- " * **Experiencing something (encountering)** β appreciating beauty, love, and connection with others.\n",
- " * **Facing suffering (finding meaning in hardship)** β transforming adversity into a meaningful experience.\n",
- "* **Self-Actualization (Maslow):** Humans have an innate drive to reach their full potential. Finding meaning involves pursuing personal growth, creativity, and fulfilling oneβs unique talents.\n",
- "* **Positive Psychology:** Focuses on what makes life worth living β happiness, resilience, gratitude, connection, and purpose.\n",
- "\n",
- "\n",
- "**4. Personal & Subjective Perspectives:**\n",
- "\n",
- "* **Relationships:** For many, the meaning of life is found in loving relationships with family, friends, and partners.\n",
- "* **Contribution:** Making a positive impact on the world, however small, can provide a sense of purpose. This could be through volunteering, activism, or simply being a good neighbor.\n",
- "* **Experiences:** Seeking out new experiences, learning, and exploring the world can enrich life and give it meaning.\n",
- "* **Personal Values:** Living in accordance with your core values β honesty, kindness, integrity, etc. β can provide a sense of direction and purpose.\n",
- "\n",
- "**Important Considerations:**\n",
- "\n",
- "* **Meaning is often *created*, not found.** Itβs not something passively discovered; it's actively constructed through our choices and actions.\n",
- "* **Meaning can evolve over time.** What gives your life meaning at one stage may change as you grow and experience new things.\n",
- "* **Itβs okay to not have all the answers.** The search for meaning is a lifelong journey, and itβs perfectly normal to grapple with this question.\n",
- "\n",
- "**Resources for Further Exploration:**\n",
- "\n",
- "* **Viktor Frankl's *Man's Search for Meaning***: [https://www.amazon.com/Mans-Search-Meaning-Viktor-Frankl/dp/080701427X](https://www.amazon.com/Mans-Search-Meaning-Viktor-Frankl/dp/080701427X)\n",
- "* **Existentialism:** [https://en.wikipedia.org/wiki/Existentialism](https://en.wikipedia.org/wiki/Existentialism)\n",
- "* **Buddhism:** [https://en.wikipedia.org/wiki/Buddhism](https://en.wikipedia.org/wiki/Buddhism)\n",
- "\n",
- "---\n",
- "\n",
- "**To help me give you a more tailored response, could you tell me:**\n",
- "\n",
- "* What are you hoping to get out of exploring this question? (e.g., Are you feeling lost and searching for purpose? Are you just curious about different viewpoints?)\n"
- ]
- }
- ],
- "source": [
- "model = lms.llm('gemma-3-4b-it')\n",
- "print(model.respond(\"What is the meaning of life?\"))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "6825b16a",
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "C:\\Users\\CoolA\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python312\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
- " from .autonotebook import tqdm as notebook_tqdm\n",
- "C:\\Users\\CoolA\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python312\\site-packages\\huggingface_hub\\file_download.py:143: UserWarning: `huggingface_hub` cache-system uses symlinks by default to efficiently store duplicated files but your machine does not support them in C:\\Users\\CoolA\\.cache\\huggingface\\hub\\datasets--openai--gsm8k. Caching files will still work but in a degraded version that might require more space on your disk. This warning can be disabled by setting the `HF_HUB_DISABLE_SYMLINKS_WARNING` environment variable. For more details, see https://huggingface.co/docs/huggingface_hub/how-to-cache#limitations.\n",
- "To support symlinks on Windows, you either need to activate Developer Mode or to run Python as an administrator. In order to activate developer mode, see this article: https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development\n",
- " warnings.warn(message)\n",
- "Generating train split: 100%|ββββββββββ| 7473/7473 [00:00<00:00, 1158658.65 examples/s]\n",
- "Generating test split: 100%|ββββββββββ| 1319/1319 [00:00<00:00, 344690.78 examples/s]\n"
- ]
- }
- ],
- "source": [
- "from datasets import load_dataset\n",
- "\n",
- "ds = load_dataset(\"openai/gsm8k\", \"main\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "81f56dad",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Processing question 1/200...\n",
- "Processing question 2/200...\n",
- "Processing question 3/200...\n",
- "Processing question 4/200...\n",
- "Processing question 5/200...\n",
- "Processing question 6/200...\n",
- "Processing question 7/200...\n",
- "Processing question 8/200...\n",
- "Processing question 9/200...\n",
- "Processing question 10/200...\n",
- "Processing question 11/200...\n",
- "Processing question 12/200...\n",
- "Processing question 13/200...\n",
- "Processing question 14/200...\n",
- "Processing question 15/200...\n",
- "Processing question 16/200...\n",
- "Processing question 17/200...\n",
- "Processing question 18/200...\n",
- "Processing question 19/200...\n",
- "Processing question 20/200...\n",
- "Processing question 21/200...\n",
- "Processing question 22/200...\n",
- "Processing question 23/200...\n",
- "Processing question 24/200...\n",
- "Processing question 25/200...\n",
- "Processing question 26/200...\n",
- "Processing question 27/200...\n",
- "Processing question 28/200...\n",
- "Processing question 29/200...\n",
- "Processing question 30/200...\n",
- "Processing question 31/200...\n",
- "Processing question 32/200...\n",
- "Processing question 33/200...\n",
- "Processing question 34/200...\n",
- "Processing question 35/200...\n",
- "Processing question 36/200...\n",
- "Processing question 37/200...\n",
- "Processing question 38/200...\n",
- "Processing question 39/200...\n",
- "Processing question 40/200...\n",
- "Processing question 41/200...\n",
- "Processing question 42/200...\n",
- "Processing question 43/200...\n",
- "Processing question 44/200...\n",
- "Processing question 45/200...\n",
- "Processing question 46/200...\n",
- "Processing question 47/200...\n",
- "Processing question 48/200...\n",
- "Processing question 49/200...\n",
- "Processing question 50/200...\n",
- "Processing question 51/200...\n",
- "Processing question 52/200...\n",
- "Processing question 53/200...\n",
- "Processing question 54/200...\n",
- "Processing question 55/200...\n",
- "Processing question 56/200...\n",
- "Processing question 57/200...\n",
- "Processing question 58/200...\n",
- "Processing question 59/200...\n",
- "Processing question 60/200...\n",
- "Processing question 61/200...\n",
- "Processing question 62/200...\n",
- "Processing question 63/200...\n",
- "Processing question 64/200...\n",
- "Processing question 65/200...\n",
- "Processing question 66/200...\n",
- "Processing question 67/200...\n",
- "Processing question 68/200...\n",
- "Processing question 69/200...\n",
- "Processing question 70/200...\n",
- "Processing question 71/200...\n",
- "Processing question 72/200...\n",
- "Processing question 73/200...\n",
- "Processing question 74/200...\n",
- "Processing question 75/200...\n",
- "Processing question 76/200...\n",
- "Processing question 77/200...\n",
- "Processing question 78/200...\n",
- "Processing question 79/200...\n",
- "Processing question 80/200...\n",
- "Processing question 81/200...\n",
- "Processing question 82/200...\n",
- "Processing question 83/200...\n",
- "Processing question 84/200...\n",
- "Processing question 85/200...\n",
- "Processing question 86/200...\n",
- "Processing question 87/200...\n",
- "Processing question 88/200...\n",
- "Processing question 89/200...\n",
- "Processing question 90/200...\n",
- "Processing question 91/200...\n",
- "Processing question 92/200...\n",
- "Processing question 93/200...\n",
- "Processing question 94/200...\n",
- "Processing question 95/200...\n",
- "Processing question 96/200...\n",
- "Processing question 97/200...\n",
- "Processing question 98/200...\n",
- "Processing question 99/200...\n",
- "Processing question 100/200...\n",
- "Processing question 101/200...\n"
- ]
- }
- ],
- "source": [
- "import pandas as pd\n",
- "import lmstudio as lms\n",
- "from datasets import load_dataset\n",
- "import json\n",
- "import random\n",
- "\n",
- "# Load dataset and prerequisites\n",
- "ds = load_dataset(\"openai/gsm8k\", \"main\")\n",
- "concepts_df = pd.read_csv(\"D:\\\\eduvlm-bench\\\\cps\\\\project-lambda\\\\gsm8k_unique_concepts.csv\")\n",
- "unique_concepts = concepts_df['Concept'].tolist()\n",
- "\n",
- "# Load model\n",
- "model = lms.llm('gemma-3-4b-it')\n",
- "\n",
- "def identify_prerequisites_for_question(question, concepts_list):\n",
- " \"\"\"\n",
- " Use LLM to identify which prerequisites are needed for a specific question\n",
- " \"\"\"\n",
- " prompt = f\"\"\"\n",
- "Given this math word problem and a list of mathematical concepts, identify which concepts are ESSENTIAL prerequisites to solve this problem.\n",
- "\n",
- "Problem: {question}\n",
- "\n",
- "Available Concepts:\n",
- "{', '.join(concepts_list)}\n",
- "\n",
- "Instructions:\n",
- "- Only list concepts that are absolutely necessary to solve this problem\n",
- "- Be precise - don't include concepts that are merely related but not required\n",
- "- Return only the concept names, separated by commas\n",
- "- If none of the listed concepts are needed, return \"None\"\n",
- "\n",
- "Essential Prerequisites:\"\"\"\n",
- " \n",
- " response = model.respond(prompt)\n",
- " # Parse the response to extract concept names\n",
- " prerequisites = [concept.strip() for concept in response.content.split(',') if concept.strip() in concepts_list]\n",
- " return prerequisites\n",
- "\n",
- "def generate_wrong_answer_with_missing_prerequisite(question, missing_concept):\n",
- " \"\"\"\n",
- " Generate wrong answer by having model pretend it doesn't know a specific concept\n",
- " \"\"\"\n",
- " prompt = f\"\"\"\n",
- "You are solving a math word problem, but you have a gap in your mathematical knowledge - you don't understand or remember how to work with \"{missing_concept}\".\n",
- "\n",
- "Problem: {question}\n",
- "\n",
- "Instructions:\n",
- "- Attempt to solve this problem step by step\n",
- "- When you encounter the concept \"{missing_concept}\", make a plausible mistake or use incorrect reasoning\n",
- "- Show your work clearly\n",
- "- Your final answer should be wrong due to the missing knowledge\n",
- "- Make the mistake realistic - something a student might actually do\n",
- "\n",
- "Your solution:\"\"\"\n",
- " \n",
- " response = model.respond(prompt)\n",
- " return response\n",
- "\n",
- "# Main processing loop for first 200 questions\n",
- "results = []\n",
- "\n",
- "for i in range(min(200, len(ds['train']))):\n",
- " question = ds['train'][i]['question']\n",
- " correct_answer = ds['train'][i]['answer']\n",
- " \n",
- " print(f\"Processing question {i+1}/200...\")\n",
- " \n",
- " # Step 1: Identify prerequisites for this specific question\n",
- " prerequisites = identify_prerequisites_for_question(question, unique_concepts)\n",
- " \n",
- " if not prerequisites:\n",
- " print(f\"No prerequisites identified for question {i+1}, skipping...\")\n",
- " continue\n",
- " \n",
- " # Step 2: Randomly select one prerequisite to remove\n",
- " missing_concept = random.choice(prerequisites)\n",
- " \n",
- " # Step 3: Generate wrong answer with missing prerequisite\n",
- " wrong_answer = generate_wrong_answer_with_missing_prerequisite(question, missing_concept)\n",
- " wrong_answer = wrong_answer.content\n",
- " \n",
- " # Store results\n",
- " result = {\n",
- " 'question_id': i,\n",
- " 'question': question,\n",
- " 'correct_answer': correct_answer,\n",
- " 'all_prerequisites': prerequisites,\n",
- " 'missing_prerequisite': missing_concept,\n",
- " 'wrong_answer': wrong_answer\n",
- " }\n",
- " \n",
- " results.append(result)\n",
- " \n",
- " # Save intermediate results every 10 questions\n",
- " if (i + 1) % 10 == 0:\n",
- " with open(f'gsm8k_wrong_answers_checkpoint_{i+1}.json', 'w') as f:\n",
- " json.dump(results, f, indent=2)\n",
- "\n",
- "# Save final results\n",
- "results_df = pd.DataFrame(results)\n",
- "results_df.to_csv('gsm8k_wrong_answers_with_missing_prerequisites.csv', index=False)\n",
- "\n",
- "print(f\"Completed processing {len(results)} questions!\")\n",
- "print(\"Results saved to 'gsm8k_wrong_answers_with_missing_prerequisites.csv'\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "da4f7c49",
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.12.10"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/project-lambda/gsm8_concepts_retry.py b/project-lambda/gsm8_concepts_retry.py
deleted file mode 100644
index 7927dc144..000000000
--- a/project-lambda/gsm8_concepts_retry.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# gsm8k_unique_concepts_with_retry.py
-
-from datasets import load_dataset
-import google.generativeai as genai
-import csv
-import time
-import os
-from dotenv import load_dotenv
-from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_message
-
-
-load_dotenv()
-gemini_api_key = os.getenv("GEMINI_API_KEY")
-
-print("Loading GSM8K dataset...")
-dataset = load_dataset("gsm8k", "main", split="train")
-subset = dataset.select(range(200))
-
-# Configure Gemini API
-genai.configure(api_key=gemini_api_key)
-model = genai.GenerativeModel("gemini-1.5-flash")
-
-# Retry logic for API calls
-@retry(
- stop=stop_after_attempt(5), # Retry up to 5 times
- wait=wait_exponential(multiplier=2, min=2, max=10), # 2s, 4s, 8s, ...
- retry=retry_if_exception_message(match="rate limit exceeded|Quota.*exceeded|429")
-)
-def get_prerequisites_with_retry(prompt):
- response = model.generate_content(prompt)
- return response.text.strip()
-
-unique_concepts = set()
-
-print("Sending prompts to Gemini Flash...")
-
-for idx, entry in enumerate(subset):
- question = entry["question"]
-
- prompt = (
- f"Problem: {question}\n"
- "Task: List the prerequisite concepts or skills that a student must understand to solve this problem.\n"
- "Provide the concepts in the correct learning order, starting from the most basic to the most advanced.\n"
- "Respond with a comma-separated list like: concept1, concept2, concept3"
- )
-
- try:
- prerequisites = get_prerequisites_with_retry(prompt)
- concepts = [c.strip().title() for c in prerequisites.split(',') if c.strip()]
- unique_concepts.update(concepts)
-
- except Exception as e:
- print(f"[{idx + 1}/200] ERROR: {str(e)}")
- continue
-
- print(f"[{idx + 1}/200] Processed")
- time.sleep(1)
-
-# Save to CSV
-output_file = "gsm8k_unique_concepts.csv"
-print(f"Saving {len(unique_concepts)} unique concepts to {output_file}...")
-
-with open(output_file, mode="w", newline='', encoding="utf-8") as f:
- writer = csv.writer(f)
- writer.writerow(["Concept"])
- for concept in sorted(unique_concepts):
- writer.writerow([concept])
-
-print("Done. File saved successfully.")
diff --git a/project-lambda/gsm8k_concept.py b/project-lambda/gsm8k_concept.py
deleted file mode 100644
index a6f5947bf..000000000
--- a/project-lambda/gsm8k_concept.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# gsm8k_concepts_extraction.py
-
-from datasets import load_dataset
-import google.generativeai as genai
-import csv
-import time
-import os
-from dotenv import load_dotenv
-
-load_dotenv()
-gemini_api_key = os.getenv("GEMINI_API_KEY")
-
-print("Loading GSM8K dataset...")
-dataset = load_dataset("gsm8k", "main", split="train")
-subset = dataset.select(range(200)) # First 200 entries
-
-genai.configure(api_key=gemini_api_key)
-model = genai.GenerativeModel("gemini-1.5-flash")
-
-unique_concepts = set()
-
-print("Sending prompts to Gemini Flash...")
-
-for idx, entry in enumerate(subset):
- question = entry["question"]
-
- prompt = (
- f"Problem: {question}\n"
- "Task: List the prerequisite concepts or skills that a student must understand to solve this problem.\n"
- "Provide the concepts in the correct learning order, starting from the most basic to the most advanced.\n"
- "Respond with a comma-separated list like: concept1, concept2, concept3"
- )
-
- try:
- response = model.generate_content(prompt)
- prerequisites = response.text.strip()
-
- # Split the response by commas and clean each concept
- concepts = [c.strip().title() for c in prerequisites.split(',') if c.strip()]
- unique_concepts.update(concepts)
-
- except Exception as e:
- print(f"[{idx + 1}/200] ERROR: {str(e)}")
- continue
-
- print(f"[{idx + 1}/200] Processed")
- time.sleep(1) # To avoid API rate limits
-
-output_file = "gsm8k_unique_concepts.csv"
-print(f"Saving {len(unique_concepts)} unique concepts to {output_file}...")
-
-with open(output_file, mode="w", newline='', encoding="utf-8") as f:
- writer = csv.writer(f)
- writer.writerow(["Concept"])
- for concept in sorted(unique_concepts):
- writer.writerow([concept])
-
-print("Done. File saved successfully.")
diff --git a/project-lambda/gsm8k_prerequisite.py b/project-lambda/gsm8k_prerequisite.py
deleted file mode 100644
index 33572fdb4..000000000
--- a/project-lambda/gsm8k_prerequisite.py
+++ /dev/null
@@ -1,70 +0,0 @@
-
-from datasets import load_dataset
-import google.generativeai as genai
-import csv
-import time
-import os
-from dotenv import load_dotenv
-
-
-load_dotenv()
-
-gemini_api_key = os.getenv("GEMINI_API_KEY")
-
-#Load GSM8K dataset
-print("Loading GSM8K dataset...")
-dataset = load_dataset("gsm8k", "main", split="train")
-
-# Select 200 questions
-subset = dataset.select(range(200))
-
-
-genai.configure(api_key=gemini_api_key)
-
-model = genai.GenerativeModel("gemini-1.5-flash")
-
-# Prepare a list to store the question and its ordered prerequisites
-results = []
-
-print("Sending prompts to Gemini Flash...")
-
-#Iterate over each question and get ordered prerequisite concepts
-for idx, entry in enumerate(subset):
- question = entry["question"]
-
- # structured prompt asking for ordered prerequisite knowledge
- prompt = (
- f"Problem: {question}\n"
- "Task: List the prerequisite concepts or skills that a student must understand to solve this problem.\n"
- "Provide the concepts in the correct learning order, starting from the most basic to the most advanced.\n"
- "Respond with a comma-separated list like: concept1, concept2, concept3"
- )
-
- try:
- response = model.generate_content(prompt)
- prerequisites = response.text.strip()
-
- except Exception as e:
- prerequisites = f"ERROR: {str(e)}"
-
- results.append({
- "question": question,
- "prerequisites": prerequisites
- })
-
- # Print progress
- print(f"[{idx + 1}/200] Processed")
-
- # Delay to avoid hitting API rate limits
- time.sleep(1)
-
-#CSV generation
-output_file = "gsm8k_ordered_prerequisites.csv"
-print(f"Saving results to {output_file}...")
-
-with open(output_file, mode="w", newline='', encoding="utf-8") as f:
- writer = csv.DictWriter(f, fieldnames=["question", "prerequisites"])
- writer.writeheader()
- writer.writerows(results)
-
-print("Done. File saved successfully.")
diff --git a/project-lambda/gsm8k_unique_concepts.csv b/project-lambda/gsm8k_unique_concepts.csv
deleted file mode 100644
index 7cb8bd918..000000000
--- a/project-lambda/gsm8k_unique_concepts.csv
+++ /dev/null
@@ -1,219 +0,0 @@
-Concept
-Times As Old As
-Twice As Old As
-Addition
-Addition And Subtraction Of Integers
-Addition And Subtraction Of Time
-Addition Of Fractions
-Addition Of Fractions With Different Denominators
-Addition Of Multiple-Digit Numbers
-Addition Of Single-Digit Numbers
-Addition Of Whole Numbers
-Addition With Carrying (Optional Depending On The Student'S Skill Level)
-Age Calculation
-And Applying Multiple Steps In A Word Problem
-Application Of Arithmetic Operations In Real-World Scenarios
-Application Of Unit Rates
-Applying A Given Formula To A Word Problem
-Applying Discounts
-Applying Multiple Steps In A Calculation
-Applying Multiplication To Solve Word Problems
-Applying Percentages To A Base Value
-Applying The Formula Distance = Speed Γ Time
-Area Of A Rectangle
-Arithmetic Operations (Addition
-Arithmetic Sequences
-Basic Addition
-Basic Addition And Subtraction
-Basic Arithmetic
-Basic Arithmetic (Addition
-Basic Arithmetic Operations (Addition
-Basic Division
-Basic Multiplication
-Basic Subtraction
-Calculating A Percentage Of A Number
-Calculating Average Speed
-Calculating Averages
-Calculating Averages (Mean)
-Calculating Hourly Rates
-Calculating Overtime Pay
-Calculating Percentage Increase
-Calculating Percentage Of A Number
-Calculating Percentages
-Calculating Percentages Of A Number
-Calculating Percentages Of A Whole Number
-Calculating Time From Rate And Distance (Or In This Case
-Combining Quantities With Different Units.
-Comparing Numbers Using Greater Than/Less Than
-Comparison Of Numbers
-Compound Growth
-Concept Of Speed And Distance
-Conversion Between Units Of Length (Feet To Inches)
-Converting Fractions To Minutes
-Converting Units (Dollars To Cents)
-Converting Units (Minutes To Hours)
-Counting
-Counting And Basic Addition
-Counting And Number Recognition
-Counting And Place Value
-Counting Objects
-Counting Whole Numbers
-Decimal Multiplication
-Decimal Numbers
-Decimal Representation Of Money
-Decimal Representation Of Percentages
-Division
-Division By Whole Numbers
-Division
-Feet
-Finding A Fraction Of A Quantity
-Finding A Fraction Of A Whole Number
-Forming And Solving Equations With One Unknown
-Forming And Solving Simple Equations
-Fraction Addition And Subtraction
-Fraction Multiplication
-Fraction Of A Quantity
-Fractions
-Fractions (Specifically Halves And Quarters)
-Fractions (Specifically Halves)
-Fractions Of A Whole Number
-Geometric Sequence/Exponential Growth
-Geometric Sequences
-Hours
-Interpreting Word Problems
-Monetary Units (Cents And Dollars)
-Money Calculations
-Multi-Step Problem Solving
-Multi-Step Word Problems
-Multiplication
-Multiplication And Division By 2 (Halving)
-Multiplication And Division Of Integers
-Multiplication By A Fraction
-Multiplication By A Whole Number
-Multiplication By Fractions
-Multiplication Of Decimals
-Multiplication Of Fractions
-Multiplication Of Fractions And Whole Numbers
-Multiplication Of Fractions By Whole Numbers
-Multiplication Of Whole Numbers
-Multiplication With Carrying
-Multiplication With Decimals
-Multiplication With Larger Numbers
-Multiplication Word Problems
-Multiplication
-Next Year'S Age
-Number Of Days In A Week
-Number Of Weeks In A Year
-Number Patterns
-Number Recognition
-Order Of Operations
-Percentage
-Percentage Calculation
-Percentage Calculations
-Percentages
-Problem Solving (Word Problems)
-Problem Solving Involving Multiple Steps
-Problem Solving/Applying Math To Real-World Situations
-Problem-Solving Using Multiple Steps
-Profit Calculation (Revenue - Cost)
-Proportion
-Proportional Reasoning
-Proportions
-Rate
-Rate And Data Size)
-Ratio
-Ratio And Proportion
-Ratios
-Reading Comprehension
-Remainders
-Rounding Up To The Nearest Whole Number
-Sentences)
-Simple Interest Calculation
-Simplifying Ratios
-Solving Algebraic Equations
-Solving Equations
-Solving Equations With One Variable
-Solving For An Unknown In A Proportion
-Solving Linear Equations
-Solving Multi-Step Equations
-Solving Multi-Step Word Problems
-Solving One-Step Equations
-Solving Proportions
-Solving Simple Algebraic Equations
-Solving Simple Equations
-Solving Simultaneous Equations (Or A Logical Approach To Subtracting Overlapping Percentages).
-Solving Word Problems
-Solving Word Problems Involving Multiple Steps
-Solving Word Problems Involving Subtraction
-Solving Word Problems With Multiple Steps
-Subtraction
-Subtraction Of Fractions
-Subtraction Of Whole Numbers
-Subtraction)
-Telling Time (Minutes And Hours)
-Time Conversion (Minutes To Hours)
-Time Units And Conversions
-Time Units Conversion
-Translating Word Problems Into Algebraic Equations
-Translating Word Problems Into Algebraic Expressions
-Translating Word Problems Into Equations
-Translating Word Problems Into Mathematical Equations
-Two-Step Problem Solving
-Two-Step Word Problem Solving
-Two-Step Word Problems
-Understanding Averages
-Understanding Comparative Statements (E.G.
-Understanding Comparison Sentences (More Than/Less Than)
-Understanding Fractions
-Understanding Half
-Understanding Numbers
-"Understanding Of ""Twice As Frequently"" And ""One-Third The Frequency"""
-"Understanding Of ""Twice"""
-Understanding Of A Year'S Duration (Days In A Year)
-Understanding Of Age
-"Understanding Of Comparative Statements (""Half Of"")."
-Understanding Of Fractions
-Understanding Of Fractions (Specifically Halves)
-Understanding Of Installments And Down Payments
-Understanding Of Overlapping Sets (Or Venn Diagrams Conceptually)
-Understanding Of Percentages
-Understanding Of Time Units (Minutes
-Understanding Of Units
-Understanding Of Units (Minutes
-Understanding Of Whole Numbers
-Understanding Of Word Problems
-Understanding Percentages
-Understanding Rates (Speed Of Work).
-Understanding Rates (Speed)
-Understanding Remainders
-"Understanding The Meaning Of ""Half Of"""
-"Understanding The Meaning Of ""Twice As Many"""
-Understanding Time Units (Minutes
-Understanding Units Of Measurement (Cups And Teaspoons)
-Understanding Whole Numbers
-Understanding Word Problems
-Unit Conversion
-Unit Conversion (Days To Weeks)
-Unit Conversion (Grams To Kilograms)
-Unit Conversion (Liters To Milliliters)
-Unit Conversion (Minutes To Hours)
-Unit Conversion (Months To Years)
-Unit Rates
-Units Conversion (Miles To Hours)
-Units Of Length (Inches
-Units Of Measurement
-Units Of Time (Minutes
-Volume Calculation
-Whole Number Addition
-Whole Number Addition And Subtraction
-Whole Number Arithmetic
-Whole Number Division
-Whole Number Multiplication
-Whole Number Subtraction
-Whole Numbers
-Whole-Number Addition
-Word Problem Comprehension
-Word Problem Interpretation
-Word Problem Solving
-Word Problem Translation
-Working With Fractions
diff --git a/recommendation_engine.py b/recommendation_engine.py
deleted file mode 100644
index bae57537b..000000000
--- a/recommendation_engine.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import json
-import heapq
-
-
-def load_graph(graph_path):
- with open(graph_path, 'r') as f:
- graph_data = json.load(f)
-
- graph = {}
- for link in graph_data["links"]:
- src = link["source"]
- tgt = link["target"]
- if src not in graph:
- graph[src] = []
- graph[src].append(tgt)
- return graph
-
-
-def dijkstra_recommendation(graph, start_concepts, weak_concepts, target="Sorting Algorithms"):
- # Each weak concept adds a higher "cost" to traversal
- visited = set()
- heap = []
-
- for concept in start_concepts:
- heapq.heappush(heap, (0, [concept])) # (cost, path)
-
- while heap:
- cost, path = heapq.heappop(heap)
- current = path[-1]
-
- if current == target:
- return {"path": path, "cost": cost}
-
- if current in visited:
- continue
-
- visited.add(current)
-
- for neighbor in graph.get(current, []):
- edge_cost = 5 if neighbor in weak_concepts else 1
- heapq.heappush(heap, (cost + edge_cost, path + [neighbor]))
-
- return {"path": [], "cost": float('inf')}
-if __name__ == "__main__":
- concept_graph_path = "concept_graph_full.json"
- learner_profile = {
- "learner_id": "L001",
- "mastered_concepts": ["Computation", "Algorithms"],
- "weak_concepts": ["Problem Solving"]
- }
-
- graph = load_graph(concept_graph_path)
- result = dijkstra_recommendation(
- graph,
- start_concepts=learner_profile["mastered_concepts"],
- weak_concepts=learner_profile["weak_concepts"]
- )
-
- print("Recommended Path:", result["path"])
- print("Total Cost:", result["cost"])
diff --git a/recommendations_L001.json b/recommendations_L001.json
deleted file mode 100644
index 749da0b25..000000000
--- a/recommendations_L001.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "learner_id": "L001",
- "recommended_concepts": [
- "Problem Solving"
- ]
-}
\ No newline at end of file
diff --git a/recommendations_L002.json b/recommendations_L002.json
deleted file mode 100644
index 3f448d8b5..000000000
--- a/recommendations_L002.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "learner_id": "L002",
- "recommended_concepts": [
- "Algorithms"
- ]
-}
\ No newline at end of file
diff --git a/server.js b/server.js
deleted file mode 100644
index 8155a2543..000000000
--- a/server.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const express = require('express');
-const fs = require('fs');
-const cors = require('cors');
-const app = express();
-const PORT = 5000;
-
-app.use(cors());
-
-app.get('/api/lectures', (req, res) => {
- const data = fs.readFileSync('lectures.json', 'utf-8');
- res.json(JSON.parse(data));
-});
-
-app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
diff --git a/server/package-lock.json b/server/package-lock.json
deleted file mode 100644
index 208245bab..000000000
--- a/server/package-lock.json
+++ /dev/null
@@ -1,1705 +0,0 @@
-{
- "name": "server",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "server",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "cors": "^2.8.5",
- "express": "^5.1.0"
- },
- "devDependencies": {
- "@types/body-parser": "^1.19.6",
- "@types/cors": "^2.8.19",
- "@types/express": "^5.0.3",
- "@types/node": "^24.0.1",
- "ts-node-dev": "^2.0.0",
- "typescript": "^5.8.3"
- }
- },
- "node_modules/@cspotcode/source-map-support": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
- "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "0.3.9"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.9",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
- "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.0.3",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- },
- "node_modules/@tsconfig/node10": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
- "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node12": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
- "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node14": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
- "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@tsconfig/node16": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
- "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/body-parser": {
- "version": "1.19.6",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
- "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/connect": "*",
- "@types/node": "*"
- }
- },
- "node_modules/@types/connect": {
- "version": "3.4.38",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
- "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/cors": {
- "version": "2.8.19",
- "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
- "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/express": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
- "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/body-parser": "*",
- "@types/express-serve-static-core": "^5.0.0",
- "@types/serve-static": "*"
- }
- },
- "node_modules/@types/express-serve-static-core": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
- "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/qs": "*",
- "@types/range-parser": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/http-errors": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
- "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/mime": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
- "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "24.0.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.1.tgz",
- "integrity": "sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.8.0"
- }
- },
- "node_modules/@types/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/range-parser": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
- "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/send": {
- "version": "0.17.5",
- "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
- "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/mime": "^1",
- "@types/node": "*"
- }
- },
- "node_modules/@types/serve-static": {
- "version": "1.15.8",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
- "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/http-errors": "*",
- "@types/node": "*",
- "@types/send": "*"
- }
- },
- "node_modules/@types/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/strip-json-comments": {
- "version": "0.0.30",
- "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
- "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-walk": {
- "version": "8.3.4",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
- "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/create-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
- "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
- "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/dynamic-dedupe": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
- "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "xtend": "^4.0.0"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http-errors/node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
- "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
- },
- "node_modules/make-error": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
- "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-to-regexp": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
- "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.10",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
- "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.16.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tree-kill": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
- "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "tree-kill": "cli.js"
- }
- },
- "node_modules/ts-node": {
- "version": "10.9.2",
- "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
- "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@cspotcode/source-map-support": "^0.8.0",
- "@tsconfig/node10": "^1.0.7",
- "@tsconfig/node12": "^1.0.7",
- "@tsconfig/node14": "^1.0.0",
- "@tsconfig/node16": "^1.0.2",
- "acorn": "^8.4.1",
- "acorn-walk": "^8.1.1",
- "arg": "^4.1.0",
- "create-require": "^1.1.0",
- "diff": "^4.0.1",
- "make-error": "^1.1.1",
- "v8-compile-cache-lib": "^3.0.1",
- "yn": "3.1.1"
- },
- "bin": {
- "ts-node": "dist/bin.js",
- "ts-node-cwd": "dist/bin-cwd.js",
- "ts-node-esm": "dist/bin-esm.js",
- "ts-node-script": "dist/bin-script.js",
- "ts-node-transpile-only": "dist/bin-transpile.js",
- "ts-script": "dist/bin-script-deprecated.js"
- },
- "peerDependencies": {
- "@swc/core": ">=1.2.50",
- "@swc/wasm": ">=1.2.50",
- "@types/node": "*",
- "typescript": ">=2.7"
- },
- "peerDependenciesMeta": {
- "@swc/core": {
- "optional": true
- },
- "@swc/wasm": {
- "optional": true
- }
- }
- },
- "node_modules/ts-node-dev": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz",
- "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^3.5.1",
- "dynamic-dedupe": "^0.3.0",
- "minimist": "^1.2.6",
- "mkdirp": "^1.0.4",
- "resolve": "^1.0.0",
- "rimraf": "^2.6.1",
- "source-map-support": "^0.5.12",
- "tree-kill": "^1.2.2",
- "ts-node": "^10.4.0",
- "tsconfig": "^7.0.0"
- },
- "bin": {
- "ts-node-dev": "lib/bin.js",
- "tsnd": "lib/bin.js"
- },
- "engines": {
- "node": ">=0.8.0"
- },
- "peerDependencies": {
- "node-notifier": "*",
- "typescript": "*"
- },
- "peerDependenciesMeta": {
- "node-notifier": {
- "optional": true
- }
- }
- },
- "node_modules/tsconfig": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
- "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/strip-bom": "^3.0.0",
- "@types/strip-json-comments": "0.0.30",
- "strip-bom": "^3.0.0",
- "strip-json-comments": "^2.0.0"
- }
- },
- "node_modules/type-is": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typescript": {
- "version": "5.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
- "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "7.8.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
- "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/v8-compile-cache-lib": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
- "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.4"
- }
- },
- "node_modules/yn": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
- "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- }
- }
-}
diff --git a/server/package.json b/server/package.json
deleted file mode 100644
index c5f662ba8..000000000
--- a/server/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "server",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "node dist/app.js",
- "dev": "ts-node-dev --respawn --transpile-only src/app.ts",
- "build": "tsc",
- "test": "jest",
- "watch": "tsc -w"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "type": "commonjs",
- "dependencies": {
- "cors": "^2.8.5",
- "express": "^5.1.0"
- },
- "devDependencies": {
- "@types/body-parser": "^1.19.6",
- "@types/cors": "^2.8.19",
- "@types/express": "^5.0.3",
- "@types/node": "^24.0.1",
- "ts-node-dev": "^2.0.0",
- "typescript": "^5.8.3"
- }
-}
diff --git a/server/src/app.ts b/server/src/app.ts
deleted file mode 100644
index 97ea80337..000000000
--- a/server/src/app.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// src/app.ts
-
-import express from "express";
-import bodyParser from "body-parser";
-import learningPathRoutes from "./routes/learningPath";
-import cors from 'cors';
-// frontend port
-
-
-const app = express();
-const PORT = 3000;
-
-app.use(bodyParser.json());
-app.use("/api", learningPathRoutes);
-
-app.listen(PORT, () => {
- console.log(`Server running on http://localhost:${PORT}`);
-});
-app.use(cors({ origin: 'http://localhost:5173' }));
diff --git a/team-bhavitha-dsarecommender/MIT_OCW_Scraper/extract_topics.py b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/extract_topics.py
new file mode 100644
index 000000000..a93fa0b17
--- /dev/null
+++ b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/extract_topics.py
@@ -0,0 +1,46 @@
+import fitz # PyMuPDF
+import os
+import json
+
+# Step 1: Topics to search for
+topics = ["Loops", "Algorithms", "Conditionals", "Variables", "Functions", "Recursion", "Branching", "Expressions", "Computation"]
+
+# Step 2: Extract text from PDF
+def extract_text(pdf_path):
+ text = ""
+ doc = fitz.open(pdf_path)
+ for page in doc:
+ text += page.get_text()
+ return text.strip()
+
+# Step 3: Match text with topics
+def find_topics(text):
+ found = []
+ for topic in topics:
+ if topic.lower() in text.lower():
+ found.append(topic)
+ return found
+
+# Step 4: Main script
+def main():
+ pdf_path = "mit_pdfs/lecture_01.pdf"
+ raw_text = extract_text(pdf_path)
+
+ # Save raw text
+ os.makedirs("raw_text", exist_ok=True)
+ with open("raw_text/lecture_01_raw.txt", "w", encoding="utf-8") as f:
+ f.write(raw_text)
+
+ # Find matched topics
+ matched_topics = find_topics(raw_text)
+
+ # Save concept JSON
+ os.makedirs("json_output", exist_ok=True)
+ data = [{"title": topic, "content": raw_text} for topic in matched_topics]
+ with open("json_output/lecture_01_concepts.json", "w", encoding="utf-8") as f:
+ json.dump(data, f, indent=2)
+
+ print("β
Lecture 1 processed and saved!")
+
+if __name__ == "__main__":
+ main()
diff --git a/team-bhavitha-dsarecommender/MIT_OCW_Scraper/json_output/lecture_01_concepts.json b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/json_output/lecture_01_concepts.json
new file mode 100644
index 000000000..ff9747c88
--- /dev/null
+++ b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/json_output/lecture_01_concepts.json
@@ -0,0 +1,22 @@
+[
+ {
+ "title": "Algorithms",
+ "content": "WELCOME!\n(download slides and .py files and follow along!)\n6.0001 LECTURE 1\n1\n6.0001 LECTURE 1\nTODAY\n\uf0a7course info\n\uf0a7what is computation\n\uf0a7python basics\n\uf0a7mathematical operations\n\uf0a7python variables and types\n\uf0a7NOTE: slides and code files up before each lecture\no highly encourage you to download them before lecture\no take notes and run code files when I do\no bring computers to answer in-class practice exercises!\n2\n6.0001 LECTURE 1\nCOURSE INFO\n\uf0a7Grading\n\u25e6approx. 20% Quiz\n\u25e6approx. 40% Final \n\u25e6approx. 30% Problem Sets \n\u25e6approx. 10% MITx Finger Exercises\n3\n6.0001 LECTURE 1\nCOURSE POLICIES\n\uf0a7Collaboration\n\u25e6may collaborate with anyone\n\u25e6required to write code independently and write names of \nall collaborators on submission\n\u25e6we will be running a code similarity program on all psets\n\uf0a7Extensions\n\u25e6no extensions\n\u25e6late days, see course website for details\n\u25e6drop and roll weight of max two psets in final exam grade\n\u25e6should be EMERGENCY use only\n4\n6.0001 LECTURE 1\nRECITATIONS\n\uf0a7not mandatory\n\uf0a7two flavors\n1) Lecture review: review lecture material \no if you missed lecture \no if you need a different take on the same concepts\n2) Problem solving: teach you how to solve programming \nproblems\no useful if you don\u2019t know how to set up pseudocode from pset words \no we show a couple of harder questions\no walk you through how to approach solving the problem\no brainstorm code solution along with the recitation instructor\no will post solutions after\n6.0001 LECTURE 1\n5\nFAST PACED COURSE\n\uf0a7Position yourself to succeed!\n\u25e6read psets when they come out and come back to them later\n\u25e6use late days in emergency situations\n\uf0a7New to programming? PRACTICE. PRACTICE? PRACTICE! \n\u25e6can\u2019t passively absorb programming as a skill\n\u25e6download code before lecture and follow along\n\u25e6do MITx finger exercises \n\u25e6don\u2019t be afraid to try out Python commands! \n6\n6.0001 LECTURE 1\nPRACTICE\n7\n6.0001 LECTURE 1\nPROBLEM \nSOLVING\nPROGRAMMING \nSKILL\nKNOWLEDGE \nOF CONCEPTS\nTOPICS\n\uf0a7represent knowledge with data structures\n\uf0a7iteration and recursion as computational metaphors\n\uf0a7abstraction of procedures and data types\n\uf0a7organize and modularize systems using object classes \nand methods\n\uf0a7different classes of algorithms, searching and sorting\n\uf0a7complexity of algorithms\n6.0001 LECTURE 1\n8\nWHAT DOES A COMPUTER DO\n\uf0a7Fundamentally:\n\u25e6performs calculations\na billion calculations per second!\n\u25e6remembers results\n100s of gigabytes of storage!\n\uf0a7What kinds of calculations?\n\u25e6built-in to the language\n\u25e6ones that you define as the programmer\n\uf0a7computers only know what you tell them\n6.0001 LECTURE 1\n9\nTYPES OF KNOWLEDGE\n\uf0a7declarative knowledge is statements of fact. \n\u25e6someone will win a Google \nCardboard before class ends\n\uf0a7imperative knowledge is a recipe or \u201chow-to\u201d. \n1) Students sign up for raffle\n2) Ana opens her IDE\n3) Ana chooses a random number between 1st and nth responder\n4) Ana finds the number in the responders sheet. Winner!\n6.0001 LECTURE 1\n10\nA NUMERICAL EXAMPLE\n\uf0a7square root of a number x is y such that y*y = x\n\uf0a7recipe for deducing square root of a number x (16)\n1) Start with a guess, g\n2) If g*g is close enough to x, stop and say g is the \nanswer \n3) Otherwise make a new guess by averaging g and x/g\n4) Using the new guess, repeat process until close enough\n6.0001 LECTURE 1\n11\ng\ng*g\nx/g\n(g+x/g)/2\n3\n9\n16/3\n4.17\n4.17\n17.36\n3.837\n4.0035\n4.0035\n16.0277\n3.997\n4.000002\nWHAT IS A RECIPE\n1)\nsequence of simple steps\n2)\nflow of control process that specifies when each \nstep is executed\n3)\na means of determining when to stop\n1+2+3 = an algorithm!\n6.0001 LECTURE 1\n12\nCOMPUTERS ARE MACHINES\n\uf0a7how to capture a recipe in a mechanical process\n\uf0a7fixed program computer\n\u25e6calculator\n\uf0a7stored program computer\n\u25e6machine stores and executes instructions\n6.0001 LECTURE 1\n13\nBASIC MACHINE ARCHITECTURE\n6.0001 LECTURE 1\n14\nMEMORY\nCONTROL \nUNIT\nARITHMETIC \nLOGIC UNIT\nINPUT\nOUTPUT\nprogram counter\ndo primitive ops\nSTORED PROGRAM COMPUTER\n\uf0a7sequence of instructions stored inside computer\n\u25e6built from predefined set of primitive instructions\n1)\narithmetic and logic\n2)\nsimple tests\n3)\nmoving data\n\uf0a7special program (interpreter) executes each \ninstruction in order\n\u25e6use tests to change flow of control through sequence\n\u25e6stop when done\n6.0001 LECTURE 1\n15\nBASIC PRIMITIVES\n\uf0a7Turing showed that you can compute anything using 6 \nprimitives\n\uf0a7modern programming languages have more \nconvenient set of primitives\n\uf0a7can abstract methods to create new primitives\n\uf0a7anything computable in one language is computable in \nany other programming language\n6.0001 LECTURE 1\n16\nCREATING RECIPES\n\uf0a7a programming language provides a set of primitive \noperations\n\uf0a7expressions are complex but legal combinations of \nprimitives in a programming language\n\uf0a7expressions and computations have values and \nmeanings in a programming language\n6.0001 LECTURE 1\n17\nASPECTS OF LANGUAGES\n\uf0a7primitive constructs\n\u25e6English: words\n\u25e6programming language: numbers, strings, simple \noperators\n6.0001 LECTURE 1\n18\nWord Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our\nCreative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.\nWord Cloud copyright unknown, All Right Reserved.\nThis content is excluded from our Creative\nCommons license. For more information, see\nhttps://ocw.mit.edu/help/faq-fair-use/.\nASPECTS OF LANGUAGES\n\uf0a7syntax\n\u25e6English: \"cat dog boy\" \uf0e0not syntactically valid\n\"cat hugs boy\" \uf0e0syntactically valid\n\u25e6programming language: \"hi\"5 \uf0e0not syntactically valid\n3.2*5 \uf0e0syntactically valid\n6.0001 LECTURE 1\n19\nASPECTS OF LANGUAGES\n\uf0a7static semantics is which syntactically valid strings \nhave meaning\n\u25e6English: \"I are hungry\" \uf0e0syntactically valid\nbut static semantic error\n\u25e6programming language: 3.2*5\n\uf0e0syntactically valid\n3+\"hi\" \uf0e0static semantic error\n6.0001 LECTURE 1\n20\nASPECTS OF LANGUAGES\n\uf0a7semantics is the meaning associated with a \nsyntactically correct string of symbols with no static \nsemantic errors\n\u25e6English: can have many meanings \"Flying planes \ncan be dangerous\"\n\u25e6programming languages: have only one meaning but may \nnot be what programmer intended\n6.0001 LECTURE 1\n21\nWHERE THINGS GO WRONG\n\uf0a7syntactic errors\n\u25e6common and easily caught\n\uf0a7static semantic errors\n\u25e6some languages check for these before running program\n\u25e6can cause unpredictable behavior\n\uf0a7no semantic errors but different meaning than what \nprogrammer intended\n\u25e6program crashes, stops running\n\u25e6program runs forever\n\u25e6program gives an answer but different than expected\n6.0001 LECTURE 1\n22\nPYTHON PROGRAMS\n\uf0a7a program is a sequence of definitions and commands\n\u25e6definitions evaluated \n\u25e6commands executed by Python interpreter in a shell\n\uf0a7commands (statements) instruct interpreter to do \nsomething\n\uf0a7can be typed directly in a shell or stored in a file that \nis read into the shell and evaluated\n\u25e6Problem Set 0 will introduce you to these in Anaconda\n6.0001 LECTURE 1\n23\nOBJECTS\n\uf0a7programs manipulate data objects\n\uf0a7objects have a type that defines the kinds of things \nprograms can do to them\n\u25e6Ana is a human so she can walk, speak English, etc.\n\u25e6Chewbacca is a wookie so he can walk, \u201cmwaaarhrhh\u201d, etc.\n\uf0a7objects are\n\u25e6scalar (cannot be subdivided)\n\u25e6non-scalar (have internal structure that can be accessed)\n6.0001 LECTURE 1\n24\nSCALAR OBJECTS\n\uf0a7int \u2013 represent integers, ex. 5\n\uf0a7float \u2013 represent real numbers, ex. 3.27\n\uf0a7bool \u2013 represent Boolean values True and False\n\uf0a7NoneType \u2013 special and has one value, None\n\uf0a7can use type() to see the type of an object\n>>> type(5)\nint\n>>> type(3.0)\nfloat\n6.0001 LECTURE 1\n25\nTYPE CONVERSIONS (CAST)\n\uf0a7can convert object of one type to another\n\uf0a7float(3) converts integer 3 to float 3.0\n\uf0a7int(3.9) truncates float 3.9 to integer 3\n6.0001 LECTURE 1\n26\nPRINTING TO CONSOLE\n\uf0a7to show output from code to a user, use print\ncommand\nIn [11]: 3+2\nOut[11]: 5\nIn [12]: print(3+2)\n5\n6.0001 LECTURE 1\n27\nEXPRESSIONS\n\uf0a7combine objects and operators to form expressions\n\uf0a7an expression has a value, which has a type\n\uf0a7syntax for a simple expression\n \n6.0001 LECTURE 1\n28\nOPERATORS ON ints and floats\n\uf0a7i+j\n\uf0e0the sum\n\uf0a7i-j\n\uf0e0the difference\n\uf0a7i*j\n\uf0e0the product\n\uf0a7i/j\n\uf0e0division\n\uf0a7i%j\n\uf0e0the remainder when i is divided by j\n\uf0a7i**j \uf0e0i to the power of j\n6.0001 LECTURE 1\n29\nif both are ints, result is int\nif either or both are floats, result is float\nresult is float\nSIMPLE OPERATIONS\n\uf0a7parentheses used to tell Python to do these \noperations first\n\uf0a7operator precedence without parentheses\n\u25e6**\n\u25e6*\n\u25e6/\n\u25e6+ and \u2013 executed left to right, as appear in expression\n6.0001 LECTURE 1\n30\nBINDING VARIABLES AND \nVALUES\n\uf0a7equal sign is an assignment of a value to a variable \nname\npi = 3.14159\npi_approx = 22/7\n\uf0a7value stored in computer memory\n\uf0a7an assignment binds name to value\n\uf0a7retrieve value associated with name or variable by \ninvoking the name, by typing pi\n6.0001 LECTURE 1\n31\nABSTRACTING EXPRESSIONS\n\uf0a7why give names to values of expressions?\n\uf0a7to reuse names instead of values\n\uf0a7easier to change code later\npi = 3.14159\nradius = 2.2\narea = pi*(radius**2)\n6.0001 LECTURE 1\n32\nPROGRAMMING vs MATH\n\uf0a7in programming, you do not \u201csolve for x\u201d\npi = 3.14159\nradius = 2.2\n# area of circle\narea = pi*(radius**2)\nradius = radius+1\n6.0001 LECTURE 1\n33\nCHANGING BINDINGS\n\uf0a7can re-bind variable names using new assignment \nstatements\n\uf0a7previous value may still stored in memory but lost the \nhandle for it\n\uf0a7value for area does not change until you tell the \ncomputer to do the calculation again\n6.0001 LECTURE 1\n34\npi\nradius\narea\n3.14\n2.2\n15.1976\n3.2\npi = 3.14\nradius = 2.2\narea = pi*(radius**2)\nradius = radius+1\nMIT OpenCourseWare\nhttps://ocw.mit.edu\n6.0001 Introduction to Computer Science and Programming in Python\nFall 2016\nFor information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms."
+ },
+ {
+ "title": "Variables",
+ "content": "WELCOME!\n(download slides and .py files and follow along!)\n6.0001 LECTURE 1\n1\n6.0001 LECTURE 1\nTODAY\n\uf0a7course info\n\uf0a7what is computation\n\uf0a7python basics\n\uf0a7mathematical operations\n\uf0a7python variables and types\n\uf0a7NOTE: slides and code files up before each lecture\no highly encourage you to download them before lecture\no take notes and run code files when I do\no bring computers to answer in-class practice exercises!\n2\n6.0001 LECTURE 1\nCOURSE INFO\n\uf0a7Grading\n\u25e6approx. 20% Quiz\n\u25e6approx. 40% Final \n\u25e6approx. 30% Problem Sets \n\u25e6approx. 10% MITx Finger Exercises\n3\n6.0001 LECTURE 1\nCOURSE POLICIES\n\uf0a7Collaboration\n\u25e6may collaborate with anyone\n\u25e6required to write code independently and write names of \nall collaborators on submission\n\u25e6we will be running a code similarity program on all psets\n\uf0a7Extensions\n\u25e6no extensions\n\u25e6late days, see course website for details\n\u25e6drop and roll weight of max two psets in final exam grade\n\u25e6should be EMERGENCY use only\n4\n6.0001 LECTURE 1\nRECITATIONS\n\uf0a7not mandatory\n\uf0a7two flavors\n1) Lecture review: review lecture material \no if you missed lecture \no if you need a different take on the same concepts\n2) Problem solving: teach you how to solve programming \nproblems\no useful if you don\u2019t know how to set up pseudocode from pset words \no we show a couple of harder questions\no walk you through how to approach solving the problem\no brainstorm code solution along with the recitation instructor\no will post solutions after\n6.0001 LECTURE 1\n5\nFAST PACED COURSE\n\uf0a7Position yourself to succeed!\n\u25e6read psets when they come out and come back to them later\n\u25e6use late days in emergency situations\n\uf0a7New to programming? PRACTICE. PRACTICE? PRACTICE! \n\u25e6can\u2019t passively absorb programming as a skill\n\u25e6download code before lecture and follow along\n\u25e6do MITx finger exercises \n\u25e6don\u2019t be afraid to try out Python commands! \n6\n6.0001 LECTURE 1\nPRACTICE\n7\n6.0001 LECTURE 1\nPROBLEM \nSOLVING\nPROGRAMMING \nSKILL\nKNOWLEDGE \nOF CONCEPTS\nTOPICS\n\uf0a7represent knowledge with data structures\n\uf0a7iteration and recursion as computational metaphors\n\uf0a7abstraction of procedures and data types\n\uf0a7organize and modularize systems using object classes \nand methods\n\uf0a7different classes of algorithms, searching and sorting\n\uf0a7complexity of algorithms\n6.0001 LECTURE 1\n8\nWHAT DOES A COMPUTER DO\n\uf0a7Fundamentally:\n\u25e6performs calculations\na billion calculations per second!\n\u25e6remembers results\n100s of gigabytes of storage!\n\uf0a7What kinds of calculations?\n\u25e6built-in to the language\n\u25e6ones that you define as the programmer\n\uf0a7computers only know what you tell them\n6.0001 LECTURE 1\n9\nTYPES OF KNOWLEDGE\n\uf0a7declarative knowledge is statements of fact. \n\u25e6someone will win a Google \nCardboard before class ends\n\uf0a7imperative knowledge is a recipe or \u201chow-to\u201d. \n1) Students sign up for raffle\n2) Ana opens her IDE\n3) Ana chooses a random number between 1st and nth responder\n4) Ana finds the number in the responders sheet. Winner!\n6.0001 LECTURE 1\n10\nA NUMERICAL EXAMPLE\n\uf0a7square root of a number x is y such that y*y = x\n\uf0a7recipe for deducing square root of a number x (16)\n1) Start with a guess, g\n2) If g*g is close enough to x, stop and say g is the \nanswer \n3) Otherwise make a new guess by averaging g and x/g\n4) Using the new guess, repeat process until close enough\n6.0001 LECTURE 1\n11\ng\ng*g\nx/g\n(g+x/g)/2\n3\n9\n16/3\n4.17\n4.17\n17.36\n3.837\n4.0035\n4.0035\n16.0277\n3.997\n4.000002\nWHAT IS A RECIPE\n1)\nsequence of simple steps\n2)\nflow of control process that specifies when each \nstep is executed\n3)\na means of determining when to stop\n1+2+3 = an algorithm!\n6.0001 LECTURE 1\n12\nCOMPUTERS ARE MACHINES\n\uf0a7how to capture a recipe in a mechanical process\n\uf0a7fixed program computer\n\u25e6calculator\n\uf0a7stored program computer\n\u25e6machine stores and executes instructions\n6.0001 LECTURE 1\n13\nBASIC MACHINE ARCHITECTURE\n6.0001 LECTURE 1\n14\nMEMORY\nCONTROL \nUNIT\nARITHMETIC \nLOGIC UNIT\nINPUT\nOUTPUT\nprogram counter\ndo primitive ops\nSTORED PROGRAM COMPUTER\n\uf0a7sequence of instructions stored inside computer\n\u25e6built from predefined set of primitive instructions\n1)\narithmetic and logic\n2)\nsimple tests\n3)\nmoving data\n\uf0a7special program (interpreter) executes each \ninstruction in order\n\u25e6use tests to change flow of control through sequence\n\u25e6stop when done\n6.0001 LECTURE 1\n15\nBASIC PRIMITIVES\n\uf0a7Turing showed that you can compute anything using 6 \nprimitives\n\uf0a7modern programming languages have more \nconvenient set of primitives\n\uf0a7can abstract methods to create new primitives\n\uf0a7anything computable in one language is computable in \nany other programming language\n6.0001 LECTURE 1\n16\nCREATING RECIPES\n\uf0a7a programming language provides a set of primitive \noperations\n\uf0a7expressions are complex but legal combinations of \nprimitives in a programming language\n\uf0a7expressions and computations have values and \nmeanings in a programming language\n6.0001 LECTURE 1\n17\nASPECTS OF LANGUAGES\n\uf0a7primitive constructs\n\u25e6English: words\n\u25e6programming language: numbers, strings, simple \noperators\n6.0001 LECTURE 1\n18\nWord Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our\nCreative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.\nWord Cloud copyright unknown, All Right Reserved.\nThis content is excluded from our Creative\nCommons license. For more information, see\nhttps://ocw.mit.edu/help/faq-fair-use/.\nASPECTS OF LANGUAGES\n\uf0a7syntax\n\u25e6English: \"cat dog boy\" \uf0e0not syntactically valid\n\"cat hugs boy\" \uf0e0syntactically valid\n\u25e6programming language: \"hi\"5 \uf0e0not syntactically valid\n3.2*5 \uf0e0syntactically valid\n6.0001 LECTURE 1\n19\nASPECTS OF LANGUAGES\n\uf0a7static semantics is which syntactically valid strings \nhave meaning\n\u25e6English: \"I are hungry\" \uf0e0syntactically valid\nbut static semantic error\n\u25e6programming language: 3.2*5\n\uf0e0syntactically valid\n3+\"hi\" \uf0e0static semantic error\n6.0001 LECTURE 1\n20\nASPECTS OF LANGUAGES\n\uf0a7semantics is the meaning associated with a \nsyntactically correct string of symbols with no static \nsemantic errors\n\u25e6English: can have many meanings \"Flying planes \ncan be dangerous\"\n\u25e6programming languages: have only one meaning but may \nnot be what programmer intended\n6.0001 LECTURE 1\n21\nWHERE THINGS GO WRONG\n\uf0a7syntactic errors\n\u25e6common and easily caught\n\uf0a7static semantic errors\n\u25e6some languages check for these before running program\n\u25e6can cause unpredictable behavior\n\uf0a7no semantic errors but different meaning than what \nprogrammer intended\n\u25e6program crashes, stops running\n\u25e6program runs forever\n\u25e6program gives an answer but different than expected\n6.0001 LECTURE 1\n22\nPYTHON PROGRAMS\n\uf0a7a program is a sequence of definitions and commands\n\u25e6definitions evaluated \n\u25e6commands executed by Python interpreter in a shell\n\uf0a7commands (statements) instruct interpreter to do \nsomething\n\uf0a7can be typed directly in a shell or stored in a file that \nis read into the shell and evaluated\n\u25e6Problem Set 0 will introduce you to these in Anaconda\n6.0001 LECTURE 1\n23\nOBJECTS\n\uf0a7programs manipulate data objects\n\uf0a7objects have a type that defines the kinds of things \nprograms can do to them\n\u25e6Ana is a human so she can walk, speak English, etc.\n\u25e6Chewbacca is a wookie so he can walk, \u201cmwaaarhrhh\u201d, etc.\n\uf0a7objects are\n\u25e6scalar (cannot be subdivided)\n\u25e6non-scalar (have internal structure that can be accessed)\n6.0001 LECTURE 1\n24\nSCALAR OBJECTS\n\uf0a7int \u2013 represent integers, ex. 5\n\uf0a7float \u2013 represent real numbers, ex. 3.27\n\uf0a7bool \u2013 represent Boolean values True and False\n\uf0a7NoneType \u2013 special and has one value, None\n\uf0a7can use type() to see the type of an object\n>>> type(5)\nint\n>>> type(3.0)\nfloat\n6.0001 LECTURE 1\n25\nTYPE CONVERSIONS (CAST)\n\uf0a7can convert object of one type to another\n\uf0a7float(3) converts integer 3 to float 3.0\n\uf0a7int(3.9) truncates float 3.9 to integer 3\n6.0001 LECTURE 1\n26\nPRINTING TO CONSOLE\n\uf0a7to show output from code to a user, use print\ncommand\nIn [11]: 3+2\nOut[11]: 5\nIn [12]: print(3+2)\n5\n6.0001 LECTURE 1\n27\nEXPRESSIONS\n\uf0a7combine objects and operators to form expressions\n\uf0a7an expression has a value, which has a type\n\uf0a7syntax for a simple expression\n \n6.0001 LECTURE 1\n28\nOPERATORS ON ints and floats\n\uf0a7i+j\n\uf0e0the sum\n\uf0a7i-j\n\uf0e0the difference\n\uf0a7i*j\n\uf0e0the product\n\uf0a7i/j\n\uf0e0division\n\uf0a7i%j\n\uf0e0the remainder when i is divided by j\n\uf0a7i**j \uf0e0i to the power of j\n6.0001 LECTURE 1\n29\nif both are ints, result is int\nif either or both are floats, result is float\nresult is float\nSIMPLE OPERATIONS\n\uf0a7parentheses used to tell Python to do these \noperations first\n\uf0a7operator precedence without parentheses\n\u25e6**\n\u25e6*\n\u25e6/\n\u25e6+ and \u2013 executed left to right, as appear in expression\n6.0001 LECTURE 1\n30\nBINDING VARIABLES AND \nVALUES\n\uf0a7equal sign is an assignment of a value to a variable \nname\npi = 3.14159\npi_approx = 22/7\n\uf0a7value stored in computer memory\n\uf0a7an assignment binds name to value\n\uf0a7retrieve value associated with name or variable by \ninvoking the name, by typing pi\n6.0001 LECTURE 1\n31\nABSTRACTING EXPRESSIONS\n\uf0a7why give names to values of expressions?\n\uf0a7to reuse names instead of values\n\uf0a7easier to change code later\npi = 3.14159\nradius = 2.2\narea = pi*(radius**2)\n6.0001 LECTURE 1\n32\nPROGRAMMING vs MATH\n\uf0a7in programming, you do not \u201csolve for x\u201d\npi = 3.14159\nradius = 2.2\n# area of circle\narea = pi*(radius**2)\nradius = radius+1\n6.0001 LECTURE 1\n33\nCHANGING BINDINGS\n\uf0a7can re-bind variable names using new assignment \nstatements\n\uf0a7previous value may still stored in memory but lost the \nhandle for it\n\uf0a7value for area does not change until you tell the \ncomputer to do the calculation again\n6.0001 LECTURE 1\n34\npi\nradius\narea\n3.14\n2.2\n15.1976\n3.2\npi = 3.14\nradius = 2.2\narea = pi*(radius**2)\nradius = radius+1\nMIT OpenCourseWare\nhttps://ocw.mit.edu\n6.0001 Introduction to Computer Science and Programming in Python\nFall 2016\nFor information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms."
+ },
+ {
+ "title": "Recursion",
+ "content": "WELCOME!\n(download slides and .py files and follow along!)\n6.0001 LECTURE 1\n1\n6.0001 LECTURE 1\nTODAY\n\uf0a7course info\n\uf0a7what is computation\n\uf0a7python basics\n\uf0a7mathematical operations\n\uf0a7python variables and types\n\uf0a7NOTE: slides and code files up before each lecture\no highly encourage you to download them before lecture\no take notes and run code files when I do\no bring computers to answer in-class practice exercises!\n2\n6.0001 LECTURE 1\nCOURSE INFO\n\uf0a7Grading\n\u25e6approx. 20% Quiz\n\u25e6approx. 40% Final \n\u25e6approx. 30% Problem Sets \n\u25e6approx. 10% MITx Finger Exercises\n3\n6.0001 LECTURE 1\nCOURSE POLICIES\n\uf0a7Collaboration\n\u25e6may collaborate with anyone\n\u25e6required to write code independently and write names of \nall collaborators on submission\n\u25e6we will be running a code similarity program on all psets\n\uf0a7Extensions\n\u25e6no extensions\n\u25e6late days, see course website for details\n\u25e6drop and roll weight of max two psets in final exam grade\n\u25e6should be EMERGENCY use only\n4\n6.0001 LECTURE 1\nRECITATIONS\n\uf0a7not mandatory\n\uf0a7two flavors\n1) Lecture review: review lecture material \no if you missed lecture \no if you need a different take on the same concepts\n2) Problem solving: teach you how to solve programming \nproblems\no useful if you don\u2019t know how to set up pseudocode from pset words \no we show a couple of harder questions\no walk you through how to approach solving the problem\no brainstorm code solution along with the recitation instructor\no will post solutions after\n6.0001 LECTURE 1\n5\nFAST PACED COURSE\n\uf0a7Position yourself to succeed!\n\u25e6read psets when they come out and come back to them later\n\u25e6use late days in emergency situations\n\uf0a7New to programming? PRACTICE. PRACTICE? PRACTICE! \n\u25e6can\u2019t passively absorb programming as a skill\n\u25e6download code before lecture and follow along\n\u25e6do MITx finger exercises \n\u25e6don\u2019t be afraid to try out Python commands! \n6\n6.0001 LECTURE 1\nPRACTICE\n7\n6.0001 LECTURE 1\nPROBLEM \nSOLVING\nPROGRAMMING \nSKILL\nKNOWLEDGE \nOF CONCEPTS\nTOPICS\n\uf0a7represent knowledge with data structures\n\uf0a7iteration and recursion as computational metaphors\n\uf0a7abstraction of procedures and data types\n\uf0a7organize and modularize systems using object classes \nand methods\n\uf0a7different classes of algorithms, searching and sorting\n\uf0a7complexity of algorithms\n6.0001 LECTURE 1\n8\nWHAT DOES A COMPUTER DO\n\uf0a7Fundamentally:\n\u25e6performs calculations\na billion calculations per second!\n\u25e6remembers results\n100s of gigabytes of storage!\n\uf0a7What kinds of calculations?\n\u25e6built-in to the language\n\u25e6ones that you define as the programmer\n\uf0a7computers only know what you tell them\n6.0001 LECTURE 1\n9\nTYPES OF KNOWLEDGE\n\uf0a7declarative knowledge is statements of fact. \n\u25e6someone will win a Google \nCardboard before class ends\n\uf0a7imperative knowledge is a recipe or \u201chow-to\u201d. \n1) Students sign up for raffle\n2) Ana opens her IDE\n3) Ana chooses a random number between 1st and nth responder\n4) Ana finds the number in the responders sheet. Winner!\n6.0001 LECTURE 1\n10\nA NUMERICAL EXAMPLE\n\uf0a7square root of a number x is y such that y*y = x\n\uf0a7recipe for deducing square root of a number x (16)\n1) Start with a guess, g\n2) If g*g is close enough to x, stop and say g is the \nanswer \n3) Otherwise make a new guess by averaging g and x/g\n4) Using the new guess, repeat process until close enough\n6.0001 LECTURE 1\n11\ng\ng*g\nx/g\n(g+x/g)/2\n3\n9\n16/3\n4.17\n4.17\n17.36\n3.837\n4.0035\n4.0035\n16.0277\n3.997\n4.000002\nWHAT IS A RECIPE\n1)\nsequence of simple steps\n2)\nflow of control process that specifies when each \nstep is executed\n3)\na means of determining when to stop\n1+2+3 = an algorithm!\n6.0001 LECTURE 1\n12\nCOMPUTERS ARE MACHINES\n\uf0a7how to capture a recipe in a mechanical process\n\uf0a7fixed program computer\n\u25e6calculator\n\uf0a7stored program computer\n\u25e6machine stores and executes instructions\n6.0001 LECTURE 1\n13\nBASIC MACHINE ARCHITECTURE\n6.0001 LECTURE 1\n14\nMEMORY\nCONTROL \nUNIT\nARITHMETIC \nLOGIC UNIT\nINPUT\nOUTPUT\nprogram counter\ndo primitive ops\nSTORED PROGRAM COMPUTER\n\uf0a7sequence of instructions stored inside computer\n\u25e6built from predefined set of primitive instructions\n1)\narithmetic and logic\n2)\nsimple tests\n3)\nmoving data\n\uf0a7special program (interpreter) executes each \ninstruction in order\n\u25e6use tests to change flow of control through sequence\n\u25e6stop when done\n6.0001 LECTURE 1\n15\nBASIC PRIMITIVES\n\uf0a7Turing showed that you can compute anything using 6 \nprimitives\n\uf0a7modern programming languages have more \nconvenient set of primitives\n\uf0a7can abstract methods to create new primitives\n\uf0a7anything computable in one language is computable in \nany other programming language\n6.0001 LECTURE 1\n16\nCREATING RECIPES\n\uf0a7a programming language provides a set of primitive \noperations\n\uf0a7expressions are complex but legal combinations of \nprimitives in a programming language\n\uf0a7expressions and computations have values and \nmeanings in a programming language\n6.0001 LECTURE 1\n17\nASPECTS OF LANGUAGES\n\uf0a7primitive constructs\n\u25e6English: words\n\u25e6programming language: numbers, strings, simple \noperators\n6.0001 LECTURE 1\n18\nWord Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our\nCreative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.\nWord Cloud copyright unknown, All Right Reserved.\nThis content is excluded from our Creative\nCommons license. For more information, see\nhttps://ocw.mit.edu/help/faq-fair-use/.\nASPECTS OF LANGUAGES\n\uf0a7syntax\n\u25e6English: \"cat dog boy\" \uf0e0not syntactically valid\n\"cat hugs boy\" \uf0e0syntactically valid\n\u25e6programming language: \"hi\"5 \uf0e0not syntactically valid\n3.2*5 \uf0e0syntactically valid\n6.0001 LECTURE 1\n19\nASPECTS OF LANGUAGES\n\uf0a7static semantics is which syntactically valid strings \nhave meaning\n\u25e6English: \"I are hungry\" \uf0e0syntactically valid\nbut static semantic error\n\u25e6programming language: 3.2*5\n\uf0e0syntactically valid\n3+\"hi\" \uf0e0static semantic error\n6.0001 LECTURE 1\n20\nASPECTS OF LANGUAGES\n\uf0a7semantics is the meaning associated with a \nsyntactically correct string of symbols with no static \nsemantic errors\n\u25e6English: can have many meanings \"Flying planes \ncan be dangerous\"\n\u25e6programming languages: have only one meaning but may \nnot be what programmer intended\n6.0001 LECTURE 1\n21\nWHERE THINGS GO WRONG\n\uf0a7syntactic errors\n\u25e6common and easily caught\n\uf0a7static semantic errors\n\u25e6some languages check for these before running program\n\u25e6can cause unpredictable behavior\n\uf0a7no semantic errors but different meaning than what \nprogrammer intended\n\u25e6program crashes, stops running\n\u25e6program runs forever\n\u25e6program gives an answer but different than expected\n6.0001 LECTURE 1\n22\nPYTHON PROGRAMS\n\uf0a7a program is a sequence of definitions and commands\n\u25e6definitions evaluated \n\u25e6commands executed by Python interpreter in a shell\n\uf0a7commands (statements) instruct interpreter to do \nsomething\n\uf0a7can be typed directly in a shell or stored in a file that \nis read into the shell and evaluated\n\u25e6Problem Set 0 will introduce you to these in Anaconda\n6.0001 LECTURE 1\n23\nOBJECTS\n\uf0a7programs manipulate data objects\n\uf0a7objects have a type that defines the kinds of things \nprograms can do to them\n\u25e6Ana is a human so she can walk, speak English, etc.\n\u25e6Chewbacca is a wookie so he can walk, \u201cmwaaarhrhh\u201d, etc.\n\uf0a7objects are\n\u25e6scalar (cannot be subdivided)\n\u25e6non-scalar (have internal structure that can be accessed)\n6.0001 LECTURE 1\n24\nSCALAR OBJECTS\n\uf0a7int \u2013 represent integers, ex. 5\n\uf0a7float \u2013 represent real numbers, ex. 3.27\n\uf0a7bool \u2013 represent Boolean values True and False\n\uf0a7NoneType \u2013 special and has one value, None\n\uf0a7can use type() to see the type of an object\n>>> type(5)\nint\n>>> type(3.0)\nfloat\n6.0001 LECTURE 1\n25\nTYPE CONVERSIONS (CAST)\n\uf0a7can convert object of one type to another\n\uf0a7float(3) converts integer 3 to float 3.0\n\uf0a7int(3.9) truncates float 3.9 to integer 3\n6.0001 LECTURE 1\n26\nPRINTING TO CONSOLE\n\uf0a7to show output from code to a user, use print\ncommand\nIn [11]: 3+2\nOut[11]: 5\nIn [12]: print(3+2)\n5\n6.0001 LECTURE 1\n27\nEXPRESSIONS\n\uf0a7combine objects and operators to form expressions\n\uf0a7an expression has a value, which has a type\n\uf0a7syntax for a simple expression\n \n6.0001 LECTURE 1\n28\nOPERATORS ON ints and floats\n\uf0a7i+j\n\uf0e0the sum\n\uf0a7i-j\n\uf0e0the difference\n\uf0a7i*j\n\uf0e0the product\n\uf0a7i/j\n\uf0e0division\n\uf0a7i%j\n\uf0e0the remainder when i is divided by j\n\uf0a7i**j \uf0e0i to the power of j\n6.0001 LECTURE 1\n29\nif both are ints, result is int\nif either or both are floats, result is float\nresult is float\nSIMPLE OPERATIONS\n\uf0a7parentheses used to tell Python to do these \noperations first\n\uf0a7operator precedence without parentheses\n\u25e6**\n\u25e6*\n\u25e6/\n\u25e6+ and \u2013 executed left to right, as appear in expression\n6.0001 LECTURE 1\n30\nBINDING VARIABLES AND \nVALUES\n\uf0a7equal sign is an assignment of a value to a variable \nname\npi = 3.14159\npi_approx = 22/7\n\uf0a7value stored in computer memory\n\uf0a7an assignment binds name to value\n\uf0a7retrieve value associated with name or variable by \ninvoking the name, by typing pi\n6.0001 LECTURE 1\n31\nABSTRACTING EXPRESSIONS\n\uf0a7why give names to values of expressions?\n\uf0a7to reuse names instead of values\n\uf0a7easier to change code later\npi = 3.14159\nradius = 2.2\narea = pi*(radius**2)\n6.0001 LECTURE 1\n32\nPROGRAMMING vs MATH\n\uf0a7in programming, you do not \u201csolve for x\u201d\npi = 3.14159\nradius = 2.2\n# area of circle\narea = pi*(radius**2)\nradius = radius+1\n6.0001 LECTURE 1\n33\nCHANGING BINDINGS\n\uf0a7can re-bind variable names using new assignment \nstatements\n\uf0a7previous value may still stored in memory but lost the \nhandle for it\n\uf0a7value for area does not change until you tell the \ncomputer to do the calculation again\n6.0001 LECTURE 1\n34\npi\nradius\narea\n3.14\n2.2\n15.1976\n3.2\npi = 3.14\nradius = 2.2\narea = pi*(radius**2)\nradius = radius+1\nMIT OpenCourseWare\nhttps://ocw.mit.edu\n6.0001 Introduction to Computer Science and Programming in Python\nFall 2016\nFor information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms."
+ },
+ {
+ "title": "Expressions",
+ "content": "WELCOME!\n(download slides and .py files and follow along!)\n6.0001 LECTURE 1\n1\n6.0001 LECTURE 1\nTODAY\n\uf0a7course info\n\uf0a7what is computation\n\uf0a7python basics\n\uf0a7mathematical operations\n\uf0a7python variables and types\n\uf0a7NOTE: slides and code files up before each lecture\no highly encourage you to download them before lecture\no take notes and run code files when I do\no bring computers to answer in-class practice exercises!\n2\n6.0001 LECTURE 1\nCOURSE INFO\n\uf0a7Grading\n\u25e6approx. 20% Quiz\n\u25e6approx. 40% Final \n\u25e6approx. 30% Problem Sets \n\u25e6approx. 10% MITx Finger Exercises\n3\n6.0001 LECTURE 1\nCOURSE POLICIES\n\uf0a7Collaboration\n\u25e6may collaborate with anyone\n\u25e6required to write code independently and write names of \nall collaborators on submission\n\u25e6we will be running a code similarity program on all psets\n\uf0a7Extensions\n\u25e6no extensions\n\u25e6late days, see course website for details\n\u25e6drop and roll weight of max two psets in final exam grade\n\u25e6should be EMERGENCY use only\n4\n6.0001 LECTURE 1\nRECITATIONS\n\uf0a7not mandatory\n\uf0a7two flavors\n1) Lecture review: review lecture material \no if you missed lecture \no if you need a different take on the same concepts\n2) Problem solving: teach you how to solve programming \nproblems\no useful if you don\u2019t know how to set up pseudocode from pset words \no we show a couple of harder questions\no walk you through how to approach solving the problem\no brainstorm code solution along with the recitation instructor\no will post solutions after\n6.0001 LECTURE 1\n5\nFAST PACED COURSE\n\uf0a7Position yourself to succeed!\n\u25e6read psets when they come out and come back to them later\n\u25e6use late days in emergency situations\n\uf0a7New to programming? PRACTICE. PRACTICE? PRACTICE! \n\u25e6can\u2019t passively absorb programming as a skill\n\u25e6download code before lecture and follow along\n\u25e6do MITx finger exercises \n\u25e6don\u2019t be afraid to try out Python commands! \n6\n6.0001 LECTURE 1\nPRACTICE\n7\n6.0001 LECTURE 1\nPROBLEM \nSOLVING\nPROGRAMMING \nSKILL\nKNOWLEDGE \nOF CONCEPTS\nTOPICS\n\uf0a7represent knowledge with data structures\n\uf0a7iteration and recursion as computational metaphors\n\uf0a7abstraction of procedures and data types\n\uf0a7organize and modularize systems using object classes \nand methods\n\uf0a7different classes of algorithms, searching and sorting\n\uf0a7complexity of algorithms\n6.0001 LECTURE 1\n8\nWHAT DOES A COMPUTER DO\n\uf0a7Fundamentally:\n\u25e6performs calculations\na billion calculations per second!\n\u25e6remembers results\n100s of gigabytes of storage!\n\uf0a7What kinds of calculations?\n\u25e6built-in to the language\n\u25e6ones that you define as the programmer\n\uf0a7computers only know what you tell them\n6.0001 LECTURE 1\n9\nTYPES OF KNOWLEDGE\n\uf0a7declarative knowledge is statements of fact. \n\u25e6someone will win a Google \nCardboard before class ends\n\uf0a7imperative knowledge is a recipe or \u201chow-to\u201d. \n1) Students sign up for raffle\n2) Ana opens her IDE\n3) Ana chooses a random number between 1st and nth responder\n4) Ana finds the number in the responders sheet. Winner!\n6.0001 LECTURE 1\n10\nA NUMERICAL EXAMPLE\n\uf0a7square root of a number x is y such that y*y = x\n\uf0a7recipe for deducing square root of a number x (16)\n1) Start with a guess, g\n2) If g*g is close enough to x, stop and say g is the \nanswer \n3) Otherwise make a new guess by averaging g and x/g\n4) Using the new guess, repeat process until close enough\n6.0001 LECTURE 1\n11\ng\ng*g\nx/g\n(g+x/g)/2\n3\n9\n16/3\n4.17\n4.17\n17.36\n3.837\n4.0035\n4.0035\n16.0277\n3.997\n4.000002\nWHAT IS A RECIPE\n1)\nsequence of simple steps\n2)\nflow of control process that specifies when each \nstep is executed\n3)\na means of determining when to stop\n1+2+3 = an algorithm!\n6.0001 LECTURE 1\n12\nCOMPUTERS ARE MACHINES\n\uf0a7how to capture a recipe in a mechanical process\n\uf0a7fixed program computer\n\u25e6calculator\n\uf0a7stored program computer\n\u25e6machine stores and executes instructions\n6.0001 LECTURE 1\n13\nBASIC MACHINE ARCHITECTURE\n6.0001 LECTURE 1\n14\nMEMORY\nCONTROL \nUNIT\nARITHMETIC \nLOGIC UNIT\nINPUT\nOUTPUT\nprogram counter\ndo primitive ops\nSTORED PROGRAM COMPUTER\n\uf0a7sequence of instructions stored inside computer\n\u25e6built from predefined set of primitive instructions\n1)\narithmetic and logic\n2)\nsimple tests\n3)\nmoving data\n\uf0a7special program (interpreter) executes each \ninstruction in order\n\u25e6use tests to change flow of control through sequence\n\u25e6stop when done\n6.0001 LECTURE 1\n15\nBASIC PRIMITIVES\n\uf0a7Turing showed that you can compute anything using 6 \nprimitives\n\uf0a7modern programming languages have more \nconvenient set of primitives\n\uf0a7can abstract methods to create new primitives\n\uf0a7anything computable in one language is computable in \nany other programming language\n6.0001 LECTURE 1\n16\nCREATING RECIPES\n\uf0a7a programming language provides a set of primitive \noperations\n\uf0a7expressions are complex but legal combinations of \nprimitives in a programming language\n\uf0a7expressions and computations have values and \nmeanings in a programming language\n6.0001 LECTURE 1\n17\nASPECTS OF LANGUAGES\n\uf0a7primitive constructs\n\u25e6English: words\n\u25e6programming language: numbers, strings, simple \noperators\n6.0001 LECTURE 1\n18\nWord Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our\nCreative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.\nWord Cloud copyright unknown, All Right Reserved.\nThis content is excluded from our Creative\nCommons license. For more information, see\nhttps://ocw.mit.edu/help/faq-fair-use/.\nASPECTS OF LANGUAGES\n\uf0a7syntax\n\u25e6English: \"cat dog boy\" \uf0e0not syntactically valid\n\"cat hugs boy\" \uf0e0syntactically valid\n\u25e6programming language: \"hi\"5 \uf0e0not syntactically valid\n3.2*5 \uf0e0syntactically valid\n6.0001 LECTURE 1\n19\nASPECTS OF LANGUAGES\n\uf0a7static semantics is which syntactically valid strings \nhave meaning\n\u25e6English: \"I are hungry\" \uf0e0syntactically valid\nbut static semantic error\n\u25e6programming language: 3.2*5\n\uf0e0syntactically valid\n3+\"hi\" \uf0e0static semantic error\n6.0001 LECTURE 1\n20\nASPECTS OF LANGUAGES\n\uf0a7semantics is the meaning associated with a \nsyntactically correct string of symbols with no static \nsemantic errors\n\u25e6English: can have many meanings \"Flying planes \ncan be dangerous\"\n\u25e6programming languages: have only one meaning but may \nnot be what programmer intended\n6.0001 LECTURE 1\n21\nWHERE THINGS GO WRONG\n\uf0a7syntactic errors\n\u25e6common and easily caught\n\uf0a7static semantic errors\n\u25e6some languages check for these before running program\n\u25e6can cause unpredictable behavior\n\uf0a7no semantic errors but different meaning than what \nprogrammer intended\n\u25e6program crashes, stops running\n\u25e6program runs forever\n\u25e6program gives an answer but different than expected\n6.0001 LECTURE 1\n22\nPYTHON PROGRAMS\n\uf0a7a program is a sequence of definitions and commands\n\u25e6definitions evaluated \n\u25e6commands executed by Python interpreter in a shell\n\uf0a7commands (statements) instruct interpreter to do \nsomething\n\uf0a7can be typed directly in a shell or stored in a file that \nis read into the shell and evaluated\n\u25e6Problem Set 0 will introduce you to these in Anaconda\n6.0001 LECTURE 1\n23\nOBJECTS\n\uf0a7programs manipulate data objects\n\uf0a7objects have a type that defines the kinds of things \nprograms can do to them\n\u25e6Ana is a human so she can walk, speak English, etc.\n\u25e6Chewbacca is a wookie so he can walk, \u201cmwaaarhrhh\u201d, etc.\n\uf0a7objects are\n\u25e6scalar (cannot be subdivided)\n\u25e6non-scalar (have internal structure that can be accessed)\n6.0001 LECTURE 1\n24\nSCALAR OBJECTS\n\uf0a7int \u2013 represent integers, ex. 5\n\uf0a7float \u2013 represent real numbers, ex. 3.27\n\uf0a7bool \u2013 represent Boolean values True and False\n\uf0a7NoneType \u2013 special and has one value, None\n\uf0a7can use type() to see the type of an object\n>>> type(5)\nint\n>>> type(3.0)\nfloat\n6.0001 LECTURE 1\n25\nTYPE CONVERSIONS (CAST)\n\uf0a7can convert object of one type to another\n\uf0a7float(3) converts integer 3 to float 3.0\n\uf0a7int(3.9) truncates float 3.9 to integer 3\n6.0001 LECTURE 1\n26\nPRINTING TO CONSOLE\n\uf0a7to show output from code to a user, use print\ncommand\nIn [11]: 3+2\nOut[11]: 5\nIn [12]: print(3+2)\n5\n6.0001 LECTURE 1\n27\nEXPRESSIONS\n\uf0a7combine objects and operators to form expressions\n\uf0a7an expression has a value, which has a type\n\uf0a7syntax for a simple expression\n \n6.0001 LECTURE 1\n28\nOPERATORS ON ints and floats\n\uf0a7i+j\n\uf0e0the sum\n\uf0a7i-j\n\uf0e0the difference\n\uf0a7i*j\n\uf0e0the product\n\uf0a7i/j\n\uf0e0division\n\uf0a7i%j\n\uf0e0the remainder when i is divided by j\n\uf0a7i**j \uf0e0i to the power of j\n6.0001 LECTURE 1\n29\nif both are ints, result is int\nif either or both are floats, result is float\nresult is float\nSIMPLE OPERATIONS\n\uf0a7parentheses used to tell Python to do these \noperations first\n\uf0a7operator precedence without parentheses\n\u25e6**\n\u25e6*\n\u25e6/\n\u25e6+ and \u2013 executed left to right, as appear in expression\n6.0001 LECTURE 1\n30\nBINDING VARIABLES AND \nVALUES\n\uf0a7equal sign is an assignment of a value to a variable \nname\npi = 3.14159\npi_approx = 22/7\n\uf0a7value stored in computer memory\n\uf0a7an assignment binds name to value\n\uf0a7retrieve value associated with name or variable by \ninvoking the name, by typing pi\n6.0001 LECTURE 1\n31\nABSTRACTING EXPRESSIONS\n\uf0a7why give names to values of expressions?\n\uf0a7to reuse names instead of values\n\uf0a7easier to change code later\npi = 3.14159\nradius = 2.2\narea = pi*(radius**2)\n6.0001 LECTURE 1\n32\nPROGRAMMING vs MATH\n\uf0a7in programming, you do not \u201csolve for x\u201d\npi = 3.14159\nradius = 2.2\n# area of circle\narea = pi*(radius**2)\nradius = radius+1\n6.0001 LECTURE 1\n33\nCHANGING BINDINGS\n\uf0a7can re-bind variable names using new assignment \nstatements\n\uf0a7previous value may still stored in memory but lost the \nhandle for it\n\uf0a7value for area does not change until you tell the \ncomputer to do the calculation again\n6.0001 LECTURE 1\n34\npi\nradius\narea\n3.14\n2.2\n15.1976\n3.2\npi = 3.14\nradius = 2.2\narea = pi*(radius**2)\nradius = radius+1\nMIT OpenCourseWare\nhttps://ocw.mit.edu\n6.0001 Introduction to Computer Science and Programming in Python\nFall 2016\nFor information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms."
+ },
+ {
+ "title": "Computation",
+ "content": "WELCOME!\n(download slides and .py files and follow along!)\n6.0001 LECTURE 1\n1\n6.0001 LECTURE 1\nTODAY\n\uf0a7course info\n\uf0a7what is computation\n\uf0a7python basics\n\uf0a7mathematical operations\n\uf0a7python variables and types\n\uf0a7NOTE: slides and code files up before each lecture\no highly encourage you to download them before lecture\no take notes and run code files when I do\no bring computers to answer in-class practice exercises!\n2\n6.0001 LECTURE 1\nCOURSE INFO\n\uf0a7Grading\n\u25e6approx. 20% Quiz\n\u25e6approx. 40% Final \n\u25e6approx. 30% Problem Sets \n\u25e6approx. 10% MITx Finger Exercises\n3\n6.0001 LECTURE 1\nCOURSE POLICIES\n\uf0a7Collaboration\n\u25e6may collaborate with anyone\n\u25e6required to write code independently and write names of \nall collaborators on submission\n\u25e6we will be running a code similarity program on all psets\n\uf0a7Extensions\n\u25e6no extensions\n\u25e6late days, see course website for details\n\u25e6drop and roll weight of max two psets in final exam grade\n\u25e6should be EMERGENCY use only\n4\n6.0001 LECTURE 1\nRECITATIONS\n\uf0a7not mandatory\n\uf0a7two flavors\n1) Lecture review: review lecture material \no if you missed lecture \no if you need a different take on the same concepts\n2) Problem solving: teach you how to solve programming \nproblems\no useful if you don\u2019t know how to set up pseudocode from pset words \no we show a couple of harder questions\no walk you through how to approach solving the problem\no brainstorm code solution along with the recitation instructor\no will post solutions after\n6.0001 LECTURE 1\n5\nFAST PACED COURSE\n\uf0a7Position yourself to succeed!\n\u25e6read psets when they come out and come back to them later\n\u25e6use late days in emergency situations\n\uf0a7New to programming? PRACTICE. PRACTICE? PRACTICE! \n\u25e6can\u2019t passively absorb programming as a skill\n\u25e6download code before lecture and follow along\n\u25e6do MITx finger exercises \n\u25e6don\u2019t be afraid to try out Python commands! \n6\n6.0001 LECTURE 1\nPRACTICE\n7\n6.0001 LECTURE 1\nPROBLEM \nSOLVING\nPROGRAMMING \nSKILL\nKNOWLEDGE \nOF CONCEPTS\nTOPICS\n\uf0a7represent knowledge with data structures\n\uf0a7iteration and recursion as computational metaphors\n\uf0a7abstraction of procedures and data types\n\uf0a7organize and modularize systems using object classes \nand methods\n\uf0a7different classes of algorithms, searching and sorting\n\uf0a7complexity of algorithms\n6.0001 LECTURE 1\n8\nWHAT DOES A COMPUTER DO\n\uf0a7Fundamentally:\n\u25e6performs calculations\na billion calculations per second!\n\u25e6remembers results\n100s of gigabytes of storage!\n\uf0a7What kinds of calculations?\n\u25e6built-in to the language\n\u25e6ones that you define as the programmer\n\uf0a7computers only know what you tell them\n6.0001 LECTURE 1\n9\nTYPES OF KNOWLEDGE\n\uf0a7declarative knowledge is statements of fact. \n\u25e6someone will win a Google \nCardboard before class ends\n\uf0a7imperative knowledge is a recipe or \u201chow-to\u201d. \n1) Students sign up for raffle\n2) Ana opens her IDE\n3) Ana chooses a random number between 1st and nth responder\n4) Ana finds the number in the responders sheet. Winner!\n6.0001 LECTURE 1\n10\nA NUMERICAL EXAMPLE\n\uf0a7square root of a number x is y such that y*y = x\n\uf0a7recipe for deducing square root of a number x (16)\n1) Start with a guess, g\n2) If g*g is close enough to x, stop and say g is the \nanswer \n3) Otherwise make a new guess by averaging g and x/g\n4) Using the new guess, repeat process until close enough\n6.0001 LECTURE 1\n11\ng\ng*g\nx/g\n(g+x/g)/2\n3\n9\n16/3\n4.17\n4.17\n17.36\n3.837\n4.0035\n4.0035\n16.0277\n3.997\n4.000002\nWHAT IS A RECIPE\n1)\nsequence of simple steps\n2)\nflow of control process that specifies when each \nstep is executed\n3)\na means of determining when to stop\n1+2+3 = an algorithm!\n6.0001 LECTURE 1\n12\nCOMPUTERS ARE MACHINES\n\uf0a7how to capture a recipe in a mechanical process\n\uf0a7fixed program computer\n\u25e6calculator\n\uf0a7stored program computer\n\u25e6machine stores and executes instructions\n6.0001 LECTURE 1\n13\nBASIC MACHINE ARCHITECTURE\n6.0001 LECTURE 1\n14\nMEMORY\nCONTROL \nUNIT\nARITHMETIC \nLOGIC UNIT\nINPUT\nOUTPUT\nprogram counter\ndo primitive ops\nSTORED PROGRAM COMPUTER\n\uf0a7sequence of instructions stored inside computer\n\u25e6built from predefined set of primitive instructions\n1)\narithmetic and logic\n2)\nsimple tests\n3)\nmoving data\n\uf0a7special program (interpreter) executes each \ninstruction in order\n\u25e6use tests to change flow of control through sequence\n\u25e6stop when done\n6.0001 LECTURE 1\n15\nBASIC PRIMITIVES\n\uf0a7Turing showed that you can compute anything using 6 \nprimitives\n\uf0a7modern programming languages have more \nconvenient set of primitives\n\uf0a7can abstract methods to create new primitives\n\uf0a7anything computable in one language is computable in \nany other programming language\n6.0001 LECTURE 1\n16\nCREATING RECIPES\n\uf0a7a programming language provides a set of primitive \noperations\n\uf0a7expressions are complex but legal combinations of \nprimitives in a programming language\n\uf0a7expressions and computations have values and \nmeanings in a programming language\n6.0001 LECTURE 1\n17\nASPECTS OF LANGUAGES\n\uf0a7primitive constructs\n\u25e6English: words\n\u25e6programming language: numbers, strings, simple \noperators\n6.0001 LECTURE 1\n18\nWord Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our\nCreative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.\nWord Cloud copyright unknown, All Right Reserved.\nThis content is excluded from our Creative\nCommons license. For more information, see\nhttps://ocw.mit.edu/help/faq-fair-use/.\nASPECTS OF LANGUAGES\n\uf0a7syntax\n\u25e6English: \"cat dog boy\" \uf0e0not syntactically valid\n\"cat hugs boy\" \uf0e0syntactically valid\n\u25e6programming language: \"hi\"5 \uf0e0not syntactically valid\n3.2*5 \uf0e0syntactically valid\n6.0001 LECTURE 1\n19\nASPECTS OF LANGUAGES\n\uf0a7static semantics is which syntactically valid strings \nhave meaning\n\u25e6English: \"I are hungry\" \uf0e0syntactically valid\nbut static semantic error\n\u25e6programming language: 3.2*5\n\uf0e0syntactically valid\n3+\"hi\" \uf0e0static semantic error\n6.0001 LECTURE 1\n20\nASPECTS OF LANGUAGES\n\uf0a7semantics is the meaning associated with a \nsyntactically correct string of symbols with no static \nsemantic errors\n\u25e6English: can have many meanings \"Flying planes \ncan be dangerous\"\n\u25e6programming languages: have only one meaning but may \nnot be what programmer intended\n6.0001 LECTURE 1\n21\nWHERE THINGS GO WRONG\n\uf0a7syntactic errors\n\u25e6common and easily caught\n\uf0a7static semantic errors\n\u25e6some languages check for these before running program\n\u25e6can cause unpredictable behavior\n\uf0a7no semantic errors but different meaning than what \nprogrammer intended\n\u25e6program crashes, stops running\n\u25e6program runs forever\n\u25e6program gives an answer but different than expected\n6.0001 LECTURE 1\n22\nPYTHON PROGRAMS\n\uf0a7a program is a sequence of definitions and commands\n\u25e6definitions evaluated \n\u25e6commands executed by Python interpreter in a shell\n\uf0a7commands (statements) instruct interpreter to do \nsomething\n\uf0a7can be typed directly in a shell or stored in a file that \nis read into the shell and evaluated\n\u25e6Problem Set 0 will introduce you to these in Anaconda\n6.0001 LECTURE 1\n23\nOBJECTS\n\uf0a7programs manipulate data objects\n\uf0a7objects have a type that defines the kinds of things \nprograms can do to them\n\u25e6Ana is a human so she can walk, speak English, etc.\n\u25e6Chewbacca is a wookie so he can walk, \u201cmwaaarhrhh\u201d, etc.\n\uf0a7objects are\n\u25e6scalar (cannot be subdivided)\n\u25e6non-scalar (have internal structure that can be accessed)\n6.0001 LECTURE 1\n24\nSCALAR OBJECTS\n\uf0a7int \u2013 represent integers, ex. 5\n\uf0a7float \u2013 represent real numbers, ex. 3.27\n\uf0a7bool \u2013 represent Boolean values True and False\n\uf0a7NoneType \u2013 special and has one value, None\n\uf0a7can use type() to see the type of an object\n>>> type(5)\nint\n>>> type(3.0)\nfloat\n6.0001 LECTURE 1\n25\nTYPE CONVERSIONS (CAST)\n\uf0a7can convert object of one type to another\n\uf0a7float(3) converts integer 3 to float 3.0\n\uf0a7int(3.9) truncates float 3.9 to integer 3\n6.0001 LECTURE 1\n26\nPRINTING TO CONSOLE\n\uf0a7to show output from code to a user, use print\ncommand\nIn [11]: 3+2\nOut[11]: 5\nIn [12]: print(3+2)\n5\n6.0001 LECTURE 1\n27\nEXPRESSIONS\n\uf0a7combine objects and operators to form expressions\n\uf0a7an expression has a value, which has a type\n\uf0a7syntax for a simple expression\n \n6.0001 LECTURE 1\n28\nOPERATORS ON ints and floats\n\uf0a7i+j\n\uf0e0the sum\n\uf0a7i-j\n\uf0e0the difference\n\uf0a7i*j\n\uf0e0the product\n\uf0a7i/j\n\uf0e0division\n\uf0a7i%j\n\uf0e0the remainder when i is divided by j\n\uf0a7i**j \uf0e0i to the power of j\n6.0001 LECTURE 1\n29\nif both are ints, result is int\nif either or both are floats, result is float\nresult is float\nSIMPLE OPERATIONS\n\uf0a7parentheses used to tell Python to do these \noperations first\n\uf0a7operator precedence without parentheses\n\u25e6**\n\u25e6*\n\u25e6/\n\u25e6+ and \u2013 executed left to right, as appear in expression\n6.0001 LECTURE 1\n30\nBINDING VARIABLES AND \nVALUES\n\uf0a7equal sign is an assignment of a value to a variable \nname\npi = 3.14159\npi_approx = 22/7\n\uf0a7value stored in computer memory\n\uf0a7an assignment binds name to value\n\uf0a7retrieve value associated with name or variable by \ninvoking the name, by typing pi\n6.0001 LECTURE 1\n31\nABSTRACTING EXPRESSIONS\n\uf0a7why give names to values of expressions?\n\uf0a7to reuse names instead of values\n\uf0a7easier to change code later\npi = 3.14159\nradius = 2.2\narea = pi*(radius**2)\n6.0001 LECTURE 1\n32\nPROGRAMMING vs MATH\n\uf0a7in programming, you do not \u201csolve for x\u201d\npi = 3.14159\nradius = 2.2\n# area of circle\narea = pi*(radius**2)\nradius = radius+1\n6.0001 LECTURE 1\n33\nCHANGING BINDINGS\n\uf0a7can re-bind variable names using new assignment \nstatements\n\uf0a7previous value may still stored in memory but lost the \nhandle for it\n\uf0a7value for area does not change until you tell the \ncomputer to do the calculation again\n6.0001 LECTURE 1\n34\npi\nradius\narea\n3.14\n2.2\n15.1976\n3.2\npi = 3.14\nradius = 2.2\narea = pi*(radius**2)\nradius = radius+1\nMIT OpenCourseWare\nhttps://ocw.mit.edu\n6.0001 Introduction to Computer Science and Programming in Python\nFall 2016\nFor information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms."
+ }
+]
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/MIT_OCW_Scraper/mit_pdfs/lecture_01.pdf b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/mit_pdfs/lecture_01.pdf
new file mode 100644
index 000000000..da94cceb3
Binary files /dev/null and b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/mit_pdfs/lecture_01.pdf differ
diff --git a/team-bhavitha-dsarecommender/MIT_OCW_Scraper/raw_text/lecture_01_raw.txt b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/raw_text/lecture_01_raw.txt
new file mode 100644
index 000000000..44024a495
--- /dev/null
+++ b/team-bhavitha-dsarecommender/MIT_OCW_Scraper/raw_text/lecture_01_raw.txt
@@ -0,0 +1,389 @@
+WELCOME!
+(download slides and .py files and follow along!)
+6.0001 LECTURE 1
+1
+6.0001 LECTURE 1
+TODAY
+ο§course info
+ο§what is computation
+ο§python basics
+ο§mathematical operations
+ο§python variables and types
+ο§NOTE: slides and code files up before each lecture
+o highly encourage you to download them before lecture
+o take notes and run code files when I do
+o bring computers to answer in-class practice exercises!
+2
+6.0001 LECTURE 1
+COURSE INFO
+ο§Grading
+β¦approx. 20% Quiz
+β¦approx. 40% Final
+β¦approx. 30% Problem Sets
+β¦approx. 10% MITx Finger Exercises
+3
+6.0001 LECTURE 1
+COURSE POLICIES
+ο§Collaboration
+β¦may collaborate with anyone
+β¦required to write code independently and write names of
+all collaborators on submission
+β¦we will be running a code similarity program on all psets
+ο§Extensions
+β¦no extensions
+β¦late days, see course website for details
+β¦drop and roll weight of max two psets in final exam grade
+β¦should be EMERGENCY use only
+4
+6.0001 LECTURE 1
+RECITATIONS
+ο§not mandatory
+ο§two flavors
+1) Lecture review: review lecture material
+o if you missed lecture
+o if you need a different take on the same concepts
+2) Problem solving: teach you how to solve programming
+problems
+o useful if you donβt know how to set up pseudocode from pset words
+o we show a couple of harder questions
+o walk you through how to approach solving the problem
+o brainstorm code solution along with the recitation instructor
+o will post solutions after
+6.0001 LECTURE 1
+5
+FAST PACED COURSE
+ο§Position yourself to succeed!
+β¦read psets when they come out and come back to them later
+β¦use late days in emergency situations
+ο§New to programming? PRACTICE. PRACTICE? PRACTICE!
+β¦canβt passively absorb programming as a skill
+β¦download code before lecture and follow along
+β¦do MITx finger exercises
+β¦donβt be afraid to try out Python commands!
+6
+6.0001 LECTURE 1
+PRACTICE
+7
+6.0001 LECTURE 1
+PROBLEM
+SOLVING
+PROGRAMMING
+SKILL
+KNOWLEDGE
+OF CONCEPTS
+TOPICS
+ο§represent knowledge with data structures
+ο§iteration and recursion as computational metaphors
+ο§abstraction of procedures and data types
+ο§organize and modularize systems using object classes
+and methods
+ο§different classes of algorithms, searching and sorting
+ο§complexity of algorithms
+6.0001 LECTURE 1
+8
+WHAT DOES A COMPUTER DO
+ο§Fundamentally:
+β¦performs calculations
+a billion calculations per second!
+β¦remembers results
+100s of gigabytes of storage!
+ο§What kinds of calculations?
+β¦built-in to the language
+β¦ones that you define as the programmer
+ο§computers only know what you tell them
+6.0001 LECTURE 1
+9
+TYPES OF KNOWLEDGE
+ο§declarative knowledge is statements of fact.
+β¦someone will win a Google
+Cardboard before class ends
+ο§imperative knowledge is a recipe or βhow-toβ.
+1) Students sign up for raffle
+2) Ana opens her IDE
+3) Ana chooses a random number between 1st and nth responder
+4) Ana finds the number in the responders sheet. Winner!
+6.0001 LECTURE 1
+10
+A NUMERICAL EXAMPLE
+ο§square root of a number x is y such that y*y = x
+ο§recipe for deducing square root of a number x (16)
+1) Start with a guess, g
+2) If g*g is close enough to x, stop and say g is the
+answer
+3) Otherwise make a new guess by averaging g and x/g
+4) Using the new guess, repeat process until close enough
+6.0001 LECTURE 1
+11
+g
+g*g
+x/g
+(g+x/g)/2
+3
+9
+16/3
+4.17
+4.17
+17.36
+3.837
+4.0035
+4.0035
+16.0277
+3.997
+4.000002
+WHAT IS A RECIPE
+1)
+sequence of simple steps
+2)
+flow of control process that specifies when each
+step is executed
+3)
+a means of determining when to stop
+1+2+3 = an algorithm!
+6.0001 LECTURE 1
+12
+COMPUTERS ARE MACHINES
+ο§how to capture a recipe in a mechanical process
+ο§fixed program computer
+β¦calculator
+ο§stored program computer
+β¦machine stores and executes instructions
+6.0001 LECTURE 1
+13
+BASIC MACHINE ARCHITECTURE
+6.0001 LECTURE 1
+14
+MEMORY
+CONTROL
+UNIT
+ARITHMETIC
+LOGIC UNIT
+INPUT
+OUTPUT
+program counter
+do primitive ops
+STORED PROGRAM COMPUTER
+ο§sequence of instructions stored inside computer
+β¦built from predefined set of primitive instructions
+1)
+arithmetic and logic
+2)
+simple tests
+3)
+moving data
+ο§special program (interpreter) executes each
+instruction in order
+β¦use tests to change flow of control through sequence
+β¦stop when done
+6.0001 LECTURE 1
+15
+BASIC PRIMITIVES
+ο§Turing showed that you can compute anything using 6
+primitives
+ο§modern programming languages have more
+convenient set of primitives
+ο§can abstract methods to create new primitives
+ο§anything computable in one language is computable in
+any other programming language
+6.0001 LECTURE 1
+16
+CREATING RECIPES
+ο§a programming language provides a set of primitive
+operations
+ο§expressions are complex but legal combinations of
+primitives in a programming language
+ο§expressions and computations have values and
+meanings in a programming language
+6.0001 LECTURE 1
+17
+ASPECTS OF LANGUAGES
+ο§primitive constructs
+β¦English: words
+β¦programming language: numbers, strings, simple
+operators
+6.0001 LECTURE 1
+18
+Word Cloud copyright Michael Twardos, All Right Reserved. This content is excluded from our
+Creative Commons license. For more information, see https://ocw.mit.edu/help/faq-fair-use/.
+Word Cloud copyright unknown, All Right Reserved.
+This content is excluded from our Creative
+Commons license. For more information, see
+https://ocw.mit.edu/help/faq-fair-use/.
+ASPECTS OF LANGUAGES
+ο§syntax
+β¦English: "cat dog boy" ο not syntactically valid
+"cat hugs boy" ο syntactically valid
+β¦programming language: "hi"5 ο not syntactically valid
+3.2*5 ο syntactically valid
+6.0001 LECTURE 1
+19
+ASPECTS OF LANGUAGES
+ο§static semantics is which syntactically valid strings
+have meaning
+β¦English: "I are hungry" ο syntactically valid
+but static semantic error
+β¦programming language: 3.2*5
+ο syntactically valid
+3+"hi" ο static semantic error
+6.0001 LECTURE 1
+20
+ASPECTS OF LANGUAGES
+ο§semantics is the meaning associated with a
+syntactically correct string of symbols with no static
+semantic errors
+β¦English: can have many meanings "Flying planes
+can be dangerous"
+β¦programming languages: have only one meaning but may
+not be what programmer intended
+6.0001 LECTURE 1
+21
+WHERE THINGS GO WRONG
+ο§syntactic errors
+β¦common and easily caught
+ο§static semantic errors
+β¦some languages check for these before running program
+β¦can cause unpredictable behavior
+ο§no semantic errors but different meaning than what
+programmer intended
+β¦program crashes, stops running
+β¦program runs forever
+β¦program gives an answer but different than expected
+6.0001 LECTURE 1
+22
+PYTHON PROGRAMS
+ο§a program is a sequence of definitions and commands
+β¦definitions evaluated
+β¦commands executed by Python interpreter in a shell
+ο§commands (statements) instruct interpreter to do
+something
+ο§can be typed directly in a shell or stored in a file that
+is read into the shell and evaluated
+β¦Problem Set 0 will introduce you to these in Anaconda
+6.0001 LECTURE 1
+23
+OBJECTS
+ο§programs manipulate data objects
+ο§objects have a type that defines the kinds of things
+programs can do to them
+β¦Ana is a human so she can walk, speak English, etc.
+β¦Chewbacca is a wookie so he can walk, βmwaaarhrhhβ, etc.
+ο§objects are
+β¦scalar (cannot be subdivided)
+β¦non-scalar (have internal structure that can be accessed)
+6.0001 LECTURE 1
+24
+SCALAR OBJECTS
+ο§int β represent integers, ex. 5
+ο§float β represent real numbers, ex. 3.27
+ο§bool β represent Boolean values True and False
+ο§NoneType β special and has one value, None
+ο§can use type() to see the type of an object
+>>> type(5)
+int
+>>> type(3.0)
+float
+6.0001 LECTURE 1
+25
+TYPE CONVERSIONS (CAST)
+ο§can convert object of one type to another
+ο§float(3) converts integer 3 to float 3.0
+ο§int(3.9) truncates float 3.9 to integer 3
+6.0001 LECTURE 1
+26
+PRINTING TO CONSOLE
+ο§to show output from code to a user, use print
+command
+In [11]: 3+2
+Out[11]: 5
+In [12]: print(3+2)
+5
+6.0001 LECTURE 1
+27
+EXPRESSIONS
+ο§combine objects and operators to form expressions
+ο§an expression has a value, which has a type
+ο§syntax for a simple expression
+
+6.0001 LECTURE 1
+28
+OPERATORS ON ints and floats
+ο§i+j
+ο the sum
+ο§i-j
+ο the difference
+ο§i*j
+ο the product
+ο§i/j
+ο division
+ο§i%j
+ο the remainder when i is divided by j
+ο§i**j ο i to the power of j
+6.0001 LECTURE 1
+29
+if both are ints, result is int
+if either or both are floats, result is float
+result is float
+SIMPLE OPERATIONS
+ο§parentheses used to tell Python to do these
+operations first
+ο§operator precedence without parentheses
+β¦**
+β¦*
+β¦/
+β¦+ and β executed left to right, as appear in expression
+6.0001 LECTURE 1
+30
+BINDING VARIABLES AND
+VALUES
+ο§equal sign is an assignment of a value to a variable
+name
+pi = 3.14159
+pi_approx = 22/7
+ο§value stored in computer memory
+ο§an assignment binds name to value
+ο§retrieve value associated with name or variable by
+invoking the name, by typing pi
+6.0001 LECTURE 1
+31
+ABSTRACTING EXPRESSIONS
+ο§why give names to values of expressions?
+ο§to reuse names instead of values
+ο§easier to change code later
+pi = 3.14159
+radius = 2.2
+area = pi*(radius**2)
+6.0001 LECTURE 1
+32
+PROGRAMMING vs MATH
+ο§in programming, you do not βsolve for xβ
+pi = 3.14159
+radius = 2.2
+# area of circle
+area = pi*(radius**2)
+radius = radius+1
+6.0001 LECTURE 1
+33
+CHANGING BINDINGS
+ο§can re-bind variable names using new assignment
+statements
+ο§previous value may still stored in memory but lost the
+handle for it
+ο§value for area does not change until you tell the
+computer to do the calculation again
+6.0001 LECTURE 1
+34
+pi
+radius
+area
+3.14
+2.2
+15.1976
+3.2
+pi = 3.14
+radius = 2.2
+area = pi*(radius**2)
+radius = radius+1
+MIT OpenCourseWare
+https://ocw.mit.edu
+6.0001 Introduction to Computer Science and Programming in Python
+Fall 2016
+For information about citing these materials or our Terms of Use, visit: https://ocw.mit.edu/terms.
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/README.md b/team-bhavitha-dsarecommender/README.md
index 8febc4823..d178d83fc 100644
--- a/team-bhavitha-dsarecommender/README.md
+++ b/team-bhavitha-dsarecommender/README.md
@@ -1,35 +1,70 @@
-# personalized-learning-path
-Project repo for Problem Statement 2 - Personalized Learning Path Recommendation
+# Personalized Learning Path Recommendation Using Knowledge Graphs
+
+## Project Overview
+
+This project aims to develop a personalized learning system that recommends the next best concept for a student to learn, based on their prior knowledge, performance, and the logical structure of concepts in a domain like Data Structures and Algorithms (DSA).
+
+We propose using a **knowledge graph**, where each node represents a concept and edges define prerequisite relationships. The system continuously tracks each learnerβs mastery level using metrics such as quiz scores, engagement data, and attempt history. Based on this, it dynamically recommends the most suitable next concept, ensuring that all prerequisites are met before advancing.
+
+The solution will be built as a full-stack **MERN application** (MongoDB, Express, React, Node.js) with real-time recommendation logic and a user-friendly interface. A synthetic learner simulator will also be developed to test the accuracy and adaptability of the recommendation engine.
+
+The final product will be a deployable, personalized education platform that adapts to individual learning needs and promotes efficient knowledge acquisition.
+
+---
+
+### Goal
+
+To develop a personalized learning system that dynamically recommends the next best concept for a student, ensuring all prerequisites are met, and promoting efficient knowledge acquisition.
+
+## Features
+
+* **Knowledge Graph Construction:** Manually building a domain-specific knowledge graph for Data Structures and Algorithms (DSA) with defined prerequisite relationships.
+* **Learner Progress Tracking:** Real-time monitoring of individual learner progress and mastery using quiz scores, engagement data, and attempt history.
+* **Recommendation Engine:** A system that suggests the next most suitable learning concept based on the learner's current knowledge state and the knowledge graph structure.
+* **Full-Stack Web Application:** A MERN stack (MongoDB, Express, React, Node.js) application for interaction, assessment, and dynamic learning path visualization.
+* **Synthetic Learner Simulator:** A module to simulate learner behaviors for testing and evaluating the recommendation system's accuracy and adaptability.
+
+---
+
## Our Team
-Weβre a collaborative team working together on this project:
+We're a collaborative team working together on this project:
+
+| Name | Email | Role |
+| :----------------------- | :---------------------------- | :---------------- |
+| B Bhavitha | bhavitha9052004@gmail.com | T3 Team Lead |
+| Anurag Kumar | anurag2003ias@gmail.com | T3 Contributor |
+| Nishant | nishantthakurs7519@gmail.com | T3 Contributor |
+| Tamalampudi Sameer Reddy | sameerreddy213@gmail.com | T3 Contributor |
-| Name | Email | Role |
-|-----------------------|-----------------------------|-----------------|
-| B Bhavitha | bhavitha9052004@gmail.com | T3 Team Lead |
-| Anurag Kumar | anurag2003ias@gmail.com | T3 Contributor |
-| Nishant | nishantthakurs7519@gmail.com| T3 Contributor |
-| Tamalampudi Sameer Reddy| sameerreddy213@gmail.com | T3 Contributor |
+Everyone's contributions are highly valued!
+
+---
-Everyoneβs contributions are highly valued!
## Contribution Guidelines
-We welcome contributions from all team members! Hereβs how you can get started:
+We welcome contributions from all team members! Here's how you can get started:
-1. **Fork the repository** to your own GitHub account.
-2. **Clone** your fork to your local machine.
-3. **Create a new branch** for your work.
-4. Make your changes, ensuring they follow good coding practices.
-5. **Commit** your changes with a clear message.
-6. **Push** your branch to your fork.
-7. **Open a Pull Request (PR)** to the main repository.
+1. **Fork the repository** to your own GitHub account.
+2. **Clone** your fork to your local machine.
+3. **Create a new branch** for your work.
+4. Make your changes, ensuring they follow good coding practices.
+5. **Commit** your changes with a clear message.
+6. **Push** your branch to your fork.
+7. **Open a Pull Request (PR)** to the main repository.
Please make sure to:
-- Check if an issue already exists before starting new features or fixes.
-- Follow the folder structure (`client/`, `server/`, `scraper/`, `graph/`, `docs/`).
-- Add meaningful commit messages.
-- Be respectful of othersβ work β collaboration is key!
+* Check if an issue already exists before starting new features or fixes.
+* Follow the folder structure (`client/`, `server/`, `scraper/`, `graph/`, `docs/`).
+* Add meaningful commit messages.
+* Be respectful of othersβ work β collaboration is key!
Refer to [`CONTRIBUTING.md`](CONTRIBUTING.md) for more detailed guidelines.
Happy contributing!
+
+## Acknowledgements
+
+This project was developed as part of a research internship under the guidance of Prof Sudarshan Iyengar, Dept of CSE, IIT Ropar and Meenakshi V, DLED Labs, IIT Ropar.
+
+Their support, insights, and encouragement throughout the development of This Project were invaluable.
diff --git a/team-bhavitha-dsarecommender/Unconfirmed 16035.crdownload b/team-bhavitha-dsarecommender/Unconfirmed 16035.crdownload
deleted file mode 100644
index 15daac582..000000000
--- a/team-bhavitha-dsarecommender/Unconfirmed 16035.crdownload
+++ /dev/null
@@ -1,18 +0,0 @@
-import requests
-import time
-#from fake_useragent import UserAgent
-from bs4 import BeautifulSoup
-from bs4.element import Tag
-import networkx as nx
-import matplotlib.pyplot as plt
-
-url = "https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/pages/lecture-slides-code/"
-
-session = requests.Session()
-# Use a fake user agent to avoid being blocked by the server
-time.sleep(2) # Sleep to avoid overwhelming the server
-r = session.get(url)
-
-with open("lecture_slides_code.html", "w", encoding='utf-8') as f:
- f.write(r.text)
-print("HTML content retrieved and saved to lecture_slides_code.html")
diff --git a/team-bhavitha-dsarecommender/Unconfirmed 518044.crdownload b/team-bhavitha-dsarecommender/Unconfirmed 518044.crdownload
deleted file mode 100644
index 8b6636590..000000000
--- a/team-bhavitha-dsarecommender/Unconfirmed 518044.crdownload
+++ /dev/null
@@ -1,90 +0,0 @@
-from bs4 import BeautifulSoup
-from bs4.element import Tag
-import networkx as nx
-import matplotlib.pyplot as plt
-
-
-with open("lecture_slides_code.html", "r", encoding='utf-8') as f:
- html_content = f.read()
-soup = BeautifulSoup(html_content, 'html.parser')
-
-rows = soup.find_all("tr")
-
-# Extract lecture titles
-lecture_titles = []
-
-
-for row in rows:
- if isinstance(row, Tag):
- cols = row.find_all("td")
- if len(cols) >= 2:
- title = cols[1].get_text(strip=True)
- if title: # Only consider non-empty titles
- lecture_titles.append(title)
-
-# Save the lecture titles to a text file
-with open("lecture_titles.txt", "w", encoding='utf-8') as f:
- for title in lecture_titles:
- f.write(title + "\n")
-
-print(f"Extracted {len(lecture_titles)} lecture titles and saved to lecture_titles.txt")
-
-
-'''
-G = nx.DiGraph()
-
-# Added nodes and linear edges
-for i in range(len(lecture_titles)):
- G.add_node(lecture_titles[i])
- if i > 0:
- G.add_edge(lecture_titles[i - 1], lecture_titles[i])
-
-# TO visualize the graph
-plt.figure(figsize=(16, 8))
-pos = nx.spring_layout(G, k=0.8, seed=42)
-nx.draw(G, pos, with_labels=True, node_color='lightgreen', edge_color='gray',node_size=5000, font_size=4, font_weight='bold', arrows=True)
-
-plt.title("MIT 6.0001 Lecture Prerequisite Graph", fontsize=12)
-plt.axis('off')
-plt.tight_layout()
-plt.show()
-'''
-
-G = nx.DiGraph()
-
-# Added nodes and linear edges
-for i in range(len(lecture_titles)):
- G.add_node(lecture_titles[i])
- if i > 0:
- G.add_edge(lecture_titles[i - 1], lecture_titles[i])
-
-# TO visualize the graph
-plt.figure(figsize=(20, 12)) # Increased figure size
-
-# Create a hierarchical layout with more vertical spacing
-pos = nx.kamada_kawai_layout(G)
-pos_dict = {}
-import random
-for i, node in enumerate(G.nodes()):
- x, y = pos[node]
- pos_dict[node] = (x, y + i * 0.1) # Add increasing vertical displacement
-
-# Draw with adjusted parameters
-nx.draw(G, pos_dict,
- with_labels=True,
- node_color='lightgreen',
- edge_color='gray',
- node_size=2000,
- font_size=8, # Increased font size
- font_weight='bold',
- arrows=True,
- width=2, # Thicker edges
- arrowsize=10, # Larger arrows
- node_shape='o', # Circular nodes
- alpha=0.9) # Slight transparency
-
-plt.title("MIT 6.0001 Lecture Prerequisite Graph", fontsize=14, pad=20)
-plt.axis('off')
-plt.margins(0.2) # Add margins around the graph
-plt.tight_layout()
-plt.show()
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/Unconfirmed 558829.crdownload b/team-bhavitha-dsarecommender/Unconfirmed 558829.crdownload
deleted file mode 100644
index 15daac582..000000000
--- a/team-bhavitha-dsarecommender/Unconfirmed 558829.crdownload
+++ /dev/null
@@ -1,18 +0,0 @@
-import requests
-import time
-#from fake_useragent import UserAgent
-from bs4 import BeautifulSoup
-from bs4.element import Tag
-import networkx as nx
-import matplotlib.pyplot as plt
-
-url = "https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/pages/lecture-slides-code/"
-
-session = requests.Session()
-# Use a fake user agent to avoid being blocked by the server
-time.sleep(2) # Sleep to avoid overwhelming the server
-r = session.get(url)
-
-with open("lecture_slides_code.html", "w", encoding='utf-8') as f:
- f.write(r.text)
-print("HTML content retrieved and saved to lecture_slides_code.html")
diff --git a/team-bhavitha-dsarecommender/app.py b/team-bhavitha-dsarecommender/app.py
deleted file mode 100644
index c4f667746..000000000
--- a/team-bhavitha-dsarecommender/app.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from flask import Flask, request, jsonify, render_template
-from recommendation_engine import recommend_for_learner
-import os
-import json
-
-app = Flask(__name__, template_folder='templates')
-
-@app.route('/')
-def home():
- return render_template('index.html')
-
-@app.route('/recommend', methods=['POST'])
-def recommend():
- data = request.get_json()
- learner_id = data.get('learner_id')
- mastered_concepts = data.get('mastered_concepts', [])
-
- profile = {
- 'learner_id': learner_id,
- 'mastered_concepts': mastered_concepts
- }
-
- recommended = recommend_for_learner(profile)
-
- # Save recommendations to file
- os.makedirs('graph/recommendations', exist_ok=True)
- with open(f'graph/recommendations/recommendations_{learner_id}.json', 'w') as f:
- json.dump({'recommended_concepts': recommended}, f, indent=2)
-
- return jsonify({'recommended_concepts': recommended})
-
-if __name__ == '__main__':
- app.run(debug=True)
diff --git a/team-bhavitha-dsarecommender/cg_visualization.py b/team-bhavitha-dsarecommender/cg_visualization.py
deleted file mode 100644
index c9c61c4ea..000000000
--- a/team-bhavitha-dsarecommender/cg_visualization.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from pyvis.network import Network
-import networkx as nx
-import json
-from networkx.readwrite import json_graph
-
-with open("concept_graph_full.json", "r", encoding="utf-8") as f:
- data = json.load(f)
-G_loaded = json_graph.node_link_graph(data)
-
-# Created a pyvis network
-net = Network(
- height="800px",
- width="100%",
- bgcolor="#ffffff",
- font_color=True,
- directed=True
-)
-
-# Converted from networkx
-net.from_nx(G_loaded)
-#node properties
-for node in net.nodes:
- node["size"] = 20
- node["color"] = "#97C2FC"
- node["borderWidth"] = 2
- node["borderColor"] = "#2B7CE9"
- node["font"] = {"size": 12}
-
-# edge properties
-for edge in net.edges:
- edge["color"] = "#848484"
- edge["smooth"] = {"type": "continuous"}
- edge["arrows"] = "to"
- edge["arrows"] = {"to": {"enabled": True, "scaleFactor": 0.5}}
-
-# Configure dynamics
-net.set_options("""
- var options = {
- "physics": {
- "enabled": true,
- "stabilization": {"iterations": 100},
- "barnesHut": {
- "gravitationalConstant": -2000,
- "springConstant": 0.04,
- "springLength": 95
- }
- }
- }
-""")
-
-# Saved the graph
-try:
- net.write_html("concept_graph.html")
- print("Graph has been saved as 'concept_graph.html'. Please open it in a web browser to view.")
-except Exception as e:
- print(f"Error saving graph: {str(e)}")
diff --git a/team-bhavitha-dsarecommender/client/.env.development b/team-bhavitha-dsarecommender/client/.env.development
new file mode 100644
index 000000000..64c0b3772
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/.env.development
@@ -0,0 +1 @@
+VITE_API_BASE_URL=http://localhost:5000/api
diff --git a/team-bhavitha-dsarecommender/client/.env.production b/team-bhavitha-dsarecommender/client/.env.production
new file mode 100644
index 000000000..85ca0416e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/.env.production
@@ -0,0 +1,2 @@
+VITE_API_BASE_URL=https://cps-0f50.onrender.com/api
+VITE_AUTH_API_BASE_URL=https://cps-auth.vercel.app/api
diff --git a/project-alpha/frontend/.gitignore b/team-bhavitha-dsarecommender/client/.gitignore
similarity index 88%
rename from project-alpha/frontend/.gitignore
rename to team-bhavitha-dsarecommender/client/.gitignore
index a547bf36d..de964337a 100644
--- a/project-alpha/frontend/.gitignore
+++ b/team-bhavitha-dsarecommender/client/.gitignore
@@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
+.env.development
+.env.production
diff --git a/project-alpha/frontend/README.md b/team-bhavitha-dsarecommender/client/README.md
similarity index 100%
rename from project-alpha/frontend/README.md
rename to team-bhavitha-dsarecommender/client/README.md
diff --git a/project-alpha/frontend/eslint.config.js b/team-bhavitha-dsarecommender/client/eslint.config.js
similarity index 100%
rename from project-alpha/frontend/eslint.config.js
rename to team-bhavitha-dsarecommender/client/eslint.config.js
diff --git a/team-bhavitha-dsarecommender/client/index.html b/team-bhavitha-dsarecommender/client/index.html
new file mode 100644
index 000000000..89d268138
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project-alpha/frontend/package-lock.json b/team-bhavitha-dsarecommender/client/package-lock.json
similarity index 66%
rename from project-alpha/frontend/package-lock.json
rename to team-bhavitha-dsarecommender/client/package-lock.json
index 36741eab5..e94798f8b 100644
--- a/project-alpha/frontend/package-lock.json
+++ b/team-bhavitha-dsarecommender/client/package-lock.json
@@ -1,27 +1,41 @@
{
- "name": "frontend",
+ "name": "client",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "frontend",
+ "name": "client",
"version": "0.0.0",
"dependencies": {
+ "@headlessui/react": "^2.2.4",
+ "@heroicons/react": "^2.2.0",
"axios": "^1.9.0",
+ "bootstrap": "^5.3.6",
+ "framer-motion": "^12.23.0",
+ "lucide-react": "^0.525.0",
"react": "^19.1.0",
+ "react-bootstrap": "^2.10.10",
"react-dom": "^19.1.0",
- "vis-network": "^9.1.12"
+ "react-router-dom": "^7.6.2",
+ "react-select": "^5.10.1",
+ "recharts": "^2.15.3",
+ "zustand": "^5.0.5"
},
"devDependencies": {
"@eslint/js": "^9.25.0",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/react-select": "^5.0.0",
"@vitejs/plugin-react": "^4.4.1",
+ "autoprefixer": "^10.4.21",
"eslint": "^9.25.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^16.0.0",
+ "postcss": "^8.5.5",
+ "tailwindcss": "^4.1.10",
"typescript": "~5.8.3",
"typescript-eslint": "^8.30.1",
"vite": "^6.3.5"
@@ -45,7 +59,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
@@ -101,7 +114,6 @@
"version": "7.27.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
"integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.27.5",
@@ -135,7 +147,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.27.1",
@@ -177,7 +188,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -187,7 +197,6 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -221,7 +230,6 @@
"version": "7.27.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
"integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.27.3"
@@ -265,11 +273,19 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/runtime": {
+ "version": "7.27.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz",
+ "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -284,7 +300,6 @@
"version": "7.27.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz",
"integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -303,7 +318,6 @@
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -313,7 +327,6 @@
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz",
"integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -323,19 +336,126 @@
"node": ">=6.9.0"
}
},
- "node_modules/@egjs/hammerjs": {
- "version": "2.0.17",
- "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
- "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==",
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.13.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
+ "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.3.3",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
+ "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/sheet": "^1.4.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
+ "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
- "peer": true,
"dependencies": {
- "@types/hammerjs": "^2.0.36"
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.13.5",
+ "@emotion/cache": "^11.14.0",
+ "@emotion/serialize": "^1.3.3",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "hoist-non-react-statics": "^3.3.1"
},
- "engines": {
- "node": ">=0.8.0"
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
+ "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/unitless": "^0.10.0",
+ "@emotion/utils": "^1.4.2",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
+ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
+ "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
+ "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.8.0"
}
},
+ "node_modules/@emotion/utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
+ "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
+ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
+ "license": "MIT"
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
@@ -879,9 +999,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.28.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz",
- "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==",
+ "version": "9.29.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz",
+ "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -928,6 +1048,88 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.1.tgz",
+ "integrity": "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz",
+ "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.1",
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/react": {
+ "version": "0.26.28",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz",
+ "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.1.2",
+ "@floating-ui/utils": "^0.2.8",
+ "tabbable": "^6.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.3.tgz",
+ "integrity": "sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
+ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
+ "license": "MIT"
+ },
+ "node_modules/@headlessui/react": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.4.tgz",
+ "integrity": "sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react": "^0.26.16",
+ "@react-aria/focus": "^3.20.2",
+ "@react-aria/interactions": "^3.25.0",
+ "@tanstack/react-virtual": "^3.13.9",
+ "use-sync-external-store": "^1.5.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^18 || ^19 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/@heroicons/react": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
+ "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">= 16 || ^19.0.0-rc"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -998,7 +1200,6 @@
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
@@ -1013,7 +1214,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1023,7 +1223,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1033,14 +1232,12 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -1085,6 +1282,167 @@
"node": ">= 8"
}
},
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@react-aria/focus": {
+ "version": "3.20.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.20.5.tgz",
+ "integrity": "sha512-JpFtXmWQ0Oca7FcvkqgjSyo6xEP7v3oQOLUId6o0xTvm4AD5W0mU2r3lYrbhsJ+XxdUUX4AVR5473sZZ85kU4A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.3",
+ "@react-aria/utils": "^3.29.1",
+ "@react-types/shared": "^3.30.0",
+ "@swc/helpers": "^0.5.0",
+ "clsx": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/interactions": {
+ "version": "3.25.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.3.tgz",
+ "integrity": "sha512-J1bhlrNtjPS/fe5uJQ+0c7/jiXniwa4RQlP+Emjfc/iuqpW2RhbF9ou5vROcLzWIyaW8tVMZ468J68rAs/aZ5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.9",
+ "@react-aria/utils": "^3.29.1",
+ "@react-stately/flags": "^3.1.2",
+ "@react-types/shared": "^3.30.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/ssr": {
+ "version": "3.9.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.9.tgz",
+ "integrity": "sha512-2P5thfjfPy/np18e5wD4WPt8ydNXhij1jwA8oehxZTFqlgVMGXzcWKxTb4RtJrLFsqPO7RUQTiY8QJk0M4Vy2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/utils": {
+ "version": "3.29.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.29.1.tgz",
+ "integrity": "sha512-yXMFVJ73rbQ/yYE/49n5Uidjw7kh192WNN9PNQGV0Xoc7EJUlSOxqhnpHmYTyO0EotJ8fdM1fMH8durHjUSI8g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.9",
+ "@react-stately/flags": "^3.1.2",
+ "@react-stately/utils": "^3.10.7",
+ "@react-types/shared": "^3.30.0",
+ "@swc/helpers": "^0.5.0",
+ "clsx": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/flags": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.2.tgz",
+ "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@react-stately/utils": {
+ "version": "3.10.7",
+ "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.7.tgz",
+ "integrity": "sha512-cWvjGAocvy4abO9zbr6PW6taHgF24Mwy/LbQ4TC4Aq3tKdKDntxyD+sh7AkSRfJRT2ccMVaHVv2+FfHThd3PKQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/shared": {
+ "version": "3.30.0",
+ "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.30.0.tgz",
+ "integrity": "sha512-COIazDAx1ncDg046cTJ8SFYsX8aS3lB/08LDnbkH/SkdYrFPWDlXMrO/sUam8j1WWM+PJ+4d1mj7tODIKNiFog==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@restart/hooks": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
+ "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@restart/ui": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.9.4.tgz",
+ "integrity": "sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.26.0",
+ "@popperjs/core": "^2.11.8",
+ "@react-aria/ssr": "^3.5.0",
+ "@restart/hooks": "^0.5.0",
+ "@types/warning": "^3.0.3",
+ "dequal": "^2.0.3",
+ "dom-helpers": "^5.2.0",
+ "uncontrollable": "^8.0.4",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ }
+ },
+ "node_modules/@restart/ui/node_modules/@restart/hooks": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.5.1.tgz",
+ "integrity": "sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@restart/ui/node_modules/uncontrollable": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
+ "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.14.0"
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.11",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
@@ -1372,6 +1730,42 @@
"win32"
]
},
+ "node_modules/@swc/helpers": {
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
+ "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@tanstack/react-virtual": {
+ "version": "3.13.10",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.10.tgz",
+ "integrity": "sha512-nvrzk4E9mWB4124YdJ7/yzwou7IfHxlSef6ugCFcBfRmsnsma3heciiiV97sBNxyc3VuwtZvmwXd0aB5BpucVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/virtual-core": "3.13.10"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@tanstack/virtual-core": {
+ "version": "3.13.10",
+ "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.10.tgz",
+ "integrity": "sha512-sPEDhXREou5HyZYqSWIqdU580rsF6FGeN7vpzijmP3KTiOGjOMZASz4Y6+QKjiFQwhWrR58OP8izYaNGVxvViA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -1417,6 +1811,69 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/d3-array": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+ "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-ease": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-interpolate": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-color": "*"
+ }
+ },
+ "node_modules/@types/d3-path": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
+ "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-scale": {
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
+ "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-time": "*"
+ }
+ },
+ "node_modules/@types/d3-shape": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
+ "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-path": "*"
+ }
+ },
+ "node_modules/@types/d3-time": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
+ "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-timer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
+ "license": "MIT"
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -1424,12 +1881,12 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/hammerjs": {
- "version": "2.0.46",
- "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz",
- "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==",
- "license": "MIT",
- "peer": true
+ "node_modules/@types/history": {
+ "version": "4.7.11",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
+ "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
@@ -1438,11 +1895,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "license": "MIT"
+ },
"node_modules/@types/react": {
"version": "19.1.8",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz",
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.0.2"
@@ -1458,6 +1926,54 @@
"@types/react": "^19.0.0"
}
},
+ "node_modules/@types/react-router": {
+ "version": "5.1.20",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz",
+ "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/react-router-dom": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
+ "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
+ "node_modules/@types/react-select": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-5.0.0.tgz",
+ "integrity": "sha512-vddLcBpzUMVpVNmnBtpC5cyZ2ajaHx/g6SHUo6lmMw0FIiOzrtmoSQ4UI6TRl+sm8TGGT+Oir8NRMZfYQtgr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "react-select": "*"
+ }
+ },
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.12",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
+ "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/warning": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
+ "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==",
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz",
@@ -1818,24 +2334,96 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
- "node_modules/axios": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
- "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.15.6",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
- "node_modules/balanced-match": {
+ "node_modules/autoprefixer": {
+ "version": "10.4.21",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.24.4",
+ "caniuse-lite": "^1.0.30001702",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
+ "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
+ "node_modules/bootstrap": {
+ "version": "5.3.6",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.6.tgz",
+ "integrity": "sha512-jX0GAcRzvdwISuvArXn3m7KZscWWFAf1MKBcnzaN02qWMb3jpMoUX4/qgeiGzqyIb4ojulRzs89UCUmGcFSzTA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/twbs"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/bootstrap"
+ }
+ ],
+ "license": "MIT",
+ "peerDependencies": {
+ "@popperjs/core": "^2.11.8"
+ }
+ },
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
@@ -1910,16 +2498,15 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001722",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001722.tgz",
- "integrity": "sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA==",
+ "version": "1.0.30001723",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
+ "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
"dev": true,
"funding": [
{
@@ -1954,6 +2541,21 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+ "license": "MIT"
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -1986,19 +2588,6 @@
"node": ">= 0.8"
}
},
- "node_modules/component-emitter": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz",
- "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==",
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2013,6 +2602,40 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cosmiconfig/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2032,14 +2655,133 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/d3-array": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+ "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+ "license": "ISC",
+ "dependencies": {
+ "internmap": "1 - 2"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-color": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-ease": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-format": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+ "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-interpolate": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+ "license": "ISC",
+ "dependencies": {
+ "d3-color": "1 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-path": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+ "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-scale": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+ "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+ "license": "ISC",
+ "dependencies": {
+ "d3-array": "2.10.0 - 3",
+ "d3-format": "1 - 3",
+ "d3-interpolate": "1.2.0 - 3",
+ "d3-time": "2.1.1 - 3",
+ "d3-time-format": "2 - 4"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-shape": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+ "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+ "license": "ISC",
+ "dependencies": {
+ "d3-path": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-time": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+ "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+ "license": "ISC",
+ "dependencies": {
+ "d3-array": "2 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-time-format": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+ "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+ "license": "ISC",
+ "dependencies": {
+ "d3-time": "1 - 3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/d3-timer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/debug": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2053,6 +2795,12 @@
}
}
},
+ "node_modules/decimal.js-light": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
+ "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
+ "license": "MIT"
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -2069,6 +2817,37 @@
"node": ">=0.4.0"
}
},
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -2084,12 +2863,21 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.166",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.166.tgz",
- "integrity": "sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw==",
+ "version": "1.5.167",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz",
+ "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==",
"dev": true,
"license": "ISC"
},
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
@@ -2190,7 +2978,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -2200,19 +2987,19 @@
}
},
"node_modules/eslint": {
- "version": "9.28.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz",
- "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==",
+ "version": "9.29.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz",
+ "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.20.0",
+ "@eslint/config-array": "^0.20.1",
"@eslint/config-helpers": "^0.2.1",
"@eslint/core": "^0.14.0",
"@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.28.0",
+ "@eslint/js": "9.29.0",
"@eslint/plugin-kit": "^0.3.1",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@@ -2224,9 +3011,9 @@
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.3.0",
- "eslint-visitor-keys": "^4.2.0",
- "espree": "^10.3.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -2377,6 +3164,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "license": "MIT"
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2384,6 +3177,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-equals": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz",
+ "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -2464,6 +3266,12 @@
"node": ">=8"
}
},
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "license": "MIT"
+ },
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@@ -2538,6 +3346,47 @@
"node": ">= 6"
}
},
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.23.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.0.tgz",
+ "integrity": "sha512-xf6NxTGAyf7zR4r2KlnhFmsRfKIbjqeBupEDBAaEtVIBJX96sAon00kMlsKButSIRwPSHjbRrAPnYdJJ9kyhbA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.22.0",
+ "motion-utils": "^12.19.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -2703,6 +3552,21 @@
"node": ">= 0.4"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -2717,7 +3581,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -2740,25 +3603,64 @@
"node": ">=0.8.19"
}
},
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
+ "node_modules/internmap": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+ "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+ "license": "ISC",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=12"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
- },
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "license": "MIT"
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
"engines": {
"node": ">=0.10.0"
}
@@ -2780,11 +3682,22 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/jiti": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+ "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
@@ -2804,7 +3717,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -2820,6 +3732,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "license": "MIT"
+ },
"node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2847,13 +3765,6 @@
"node": ">=6"
}
},
- "node_modules/keycharm": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz",
- "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==",
- "license": "(Apache-2.0 OR MIT)",
- "peer": true
- },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -2878,6 +3789,263 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lightningcss": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
+ "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-darwin-arm64": "1.30.1",
+ "lightningcss-darwin-x64": "1.30.1",
+ "lightningcss-freebsd-x64": "1.30.1",
+ "lightningcss-linux-arm-gnueabihf": "1.30.1",
+ "lightningcss-linux-arm64-gnu": "1.30.1",
+ "lightningcss-linux-arm64-musl": "1.30.1",
+ "lightningcss-linux-x64-gnu": "1.30.1",
+ "lightningcss-linux-x64-musl": "1.30.1",
+ "lightningcss-win32-arm64-msvc": "1.30.1",
+ "lightningcss-win32-x64-msvc": "1.30.1"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
+ "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
+ "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
+ "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
+ "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
+ "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
+ "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
+ "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
+ "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
+ "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
+ "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "license": "MIT"
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -2894,6 +4062,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -2901,6 +4075,18 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -2911,6 +4097,15 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lucide-react": {
+ "version": "0.525.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz",
+ "integrity": "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -2920,6 +4115,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "license": "MIT"
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -2978,11 +4179,25 @@
"node": "*"
}
},
+ "node_modules/motion-dom": {
+ "version": "12.22.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.22.0.tgz",
+ "integrity": "sha512-ooH7+/BPw9gOsL9VtPhEJHE2m4ltnhMlcGMhEqA0YGNhKof7jdaszvsyThXI6LVIKshJUZ9/CP6HNqQhJfV7kw==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.19.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.19.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.19.0.tgz",
+ "integrity": "sha512-BuFTHINYmV07pdWs6lj6aI63vr2N4dg0vR+td0rtrdpWOhBzIkEklZyLcvKBoEtwSqx8Jg06vUB5RS0xDiUybw==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
@@ -3018,6 +4233,25 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -3072,7 +4306,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -3081,6 +4314,24 @@
"node": ">=6"
}
},
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -3101,11 +4352,25 @@
"node": ">=8"
}
},
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "license": "MIT"
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -3150,6 +4415,13 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -3160,6 +4432,42 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prop-types-extra": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
+ "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
+ "license": "MIT",
+ "dependencies": {
+ "react-is": "^16.3.2",
+ "warning": "^4.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=0.14.0"
+ }
+ },
+ "node_modules/prop-types-extra/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -3206,6 +4514,37 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-bootstrap": {
+ "version": "2.10.10",
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.10.tgz",
+ "integrity": "sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.24.7",
+ "@restart/hooks": "^0.4.9",
+ "@restart/ui": "^1.9.4",
+ "@types/prop-types": "^15.7.12",
+ "@types/react-transition-group": "^4.4.6",
+ "classnames": "^2.3.2",
+ "dom-helpers": "^5.2.1",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.8.1",
+ "prop-types-extra": "^1.1.0",
+ "react-transition-group": "^4.4.5",
+ "uncontrollable": "^7.2.1",
+ "warning": "^4.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.8",
+ "react": ">=16.14.0",
+ "react-dom": ">=16.14.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-dom": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
@@ -3218,6 +4557,18 @@
"react": "^19.1.0"
}
},
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT"
+ },
+ "node_modules/react-lifecycles-compat": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==",
+ "license": "MIT"
+ },
"node_modules/react-refresh": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
@@ -3228,11 +4579,152 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.2.tgz",
+ "integrity": "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.2.tgz",
+ "integrity": "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-select": {
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.10.1.tgz",
+ "integrity": "sha512-roPEZUL4aRZDx6DcsD+ZNreVl+fM8VsKn0Wtex1v4IazH60ILp5xhdlp464IsEAlJdXeD+BhDAFsBVMfvLQueA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.12.0",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/react": "^11.8.1",
+ "@floating-ui/dom": "^1.0.1",
+ "@types/react-transition-group": "^4.4.0",
+ "memoize-one": "^6.0.0",
+ "prop-types": "^15.6.0",
+ "react-transition-group": "^4.3.0",
+ "use-isomorphic-layout-effect": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-smooth": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
+ "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-equals": "^5.0.1",
+ "prop-types": "^15.8.1",
+ "react-transition-group": "^4.4.5"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/recharts": {
+ "version": "2.15.3",
+ "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.3.tgz",
+ "integrity": "sha512-EdOPzTwcFSuqtvkDoaM5ws/Km1+WTAO2eizL7rqiG0V2UVhTnz0m7J2i0CjVPUCdEkZImaWvXLbZDS2H5t6GFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "clsx": "^2.0.0",
+ "eventemitter3": "^4.0.1",
+ "lodash": "^4.17.21",
+ "react-is": "^18.3.1",
+ "react-smooth": "^4.0.4",
+ "recharts-scale": "^0.4.4",
+ "tiny-invariant": "^1.3.1",
+ "victory-vendor": "^36.6.8"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/recharts-scale": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
+ "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
+ "license": "MIT",
+ "dependencies": {
+ "decimal.js-light": "^2.4.1"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -3336,6 +4828,12 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3359,6 +4857,15 @@
"node": ">=8"
}
},
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -3382,6 +4889,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
+ "license": "MIT"
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -3395,6 +4908,37 @@
"node": ">=8"
}
},
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "license": "MIT"
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz",
+ "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "license": "MIT"
+ },
"node_modules/tinyglobby": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
@@ -3466,6 +5010,12 @@
"typescript": ">=4.8.4"
}
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -3516,6 +5066,21 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
+ "node_modules/uncontrollable": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
+ "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.6.3",
+ "@types/react": ">=16.9.11",
+ "invariant": "^2.2.4",
+ "react-lifecycles-compat": "^3.0.4"
+ },
+ "peerDependencies": {
+ "react": ">=15.0.0"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
@@ -3557,69 +5122,49 @@
"punycode": "^2.1.0"
}
},
- "node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
+ "node_modules/use-isomorphic-layout-effect": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz",
+ "integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==",
"license": "MIT",
- "peer": true,
- "bin": {
- "uuid": "dist/bin/uuid"
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
- "node_modules/vis-data": {
- "version": "7.1.9",
- "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.9.tgz",
- "integrity": "sha512-COQsxlVrmcRIbZMMTYwD+C2bxYCFDNQ2EHESklPiInbD/Pk3JZ6qNL84Bp9wWjYjAzXfSlsNaFtRk+hO9yBPWA==",
- "license": "(Apache-2.0 OR MIT)",
- "peer": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/visjs"
- },
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
"peerDependencies": {
- "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
- "vis-util": "^5.0.1"
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
- "node_modules/vis-network": {
- "version": "9.1.12",
- "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.1.12.tgz",
- "integrity": "sha512-kZ7eOwfK1hGwsnCsGm02M7c5WBjgwTQ7BzF9bX7JaRqntJINWyjRiFBPqeDCOoOdgLEmwCXNk/VXYcIoK0ndyw==",
- "license": "(Apache-2.0 OR MIT)",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/visjs"
- },
- "peerDependencies": {
- "@egjs/hammerjs": "^2.0.0",
- "component-emitter": "^1.3.0 || ^2.0.0",
- "keycharm": "^0.2.0 || ^0.3.0 || ^0.4.0",
- "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
- "vis-data": "^6.3.0 || ^7.0.0",
- "vis-util": "^5.0.1"
- }
- },
- "node_modules/vis-util": {
- "version": "5.0.7",
- "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.7.tgz",
- "integrity": "sha512-E3L03G3+trvc/X4LXvBfih3YIHcKS2WrP0XTdZefr6W6Qi/2nNCqZfe4JFfJU6DcQLm6Gxqj2Pfl+02859oL5A==",
- "license": "(Apache-2.0 OR MIT)",
- "peer": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/visjs"
- },
- "peerDependencies": {
- "@egjs/hammerjs": "^2.0.0",
- "component-emitter": "^1.3.0 || ^2.0.0"
+ "node_modules/victory-vendor": {
+ "version": "36.9.2",
+ "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
+ "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==",
+ "license": "MIT AND ISC",
+ "dependencies": {
+ "@types/d3-array": "^3.0.3",
+ "@types/d3-ease": "^3.0.0",
+ "@types/d3-interpolate": "^3.0.1",
+ "@types/d3-scale": "^4.0.2",
+ "@types/d3-shape": "^3.1.0",
+ "@types/d3-time": "^3.0.0",
+ "@types/d3-timer": "^3.0.0",
+ "d3-array": "^3.1.6",
+ "d3-ease": "^3.0.1",
+ "d3-interpolate": "^3.0.1",
+ "d3-scale": "^4.0.2",
+ "d3-shape": "^3.1.0",
+ "d3-time": "^3.0.0",
+ "d3-timer": "^3.0.1"
}
},
"node_modules/vite": {
@@ -3725,6 +5270,15 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/warning": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -3758,6 +5312,21 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/yaml": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
+ "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
+ "dev": true,
+ "license": "ISC",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -3770,6 +5339,35 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zustand": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.5.tgz",
+ "integrity": "sha512-mILtRfKW9xM47hqxGIxCv12gXusoY/xTSHBYApXozR0HmQv299whhBeeAcRy+KrPPybzosvJBCOmVjq6x12fCg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
}
}
}
diff --git a/project-alpha/frontend/package.json b/team-bhavitha-dsarecommender/client/package.json
similarity index 57%
rename from project-alpha/frontend/package.json
rename to team-bhavitha-dsarecommender/client/package.json
index 7a255c0e6..f35a139fc 100644
--- a/project-alpha/frontend/package.json
+++ b/team-bhavitha-dsarecommender/client/package.json
@@ -1,5 +1,5 @@
{
- "name": "frontend",
+ "name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
@@ -10,20 +10,34 @@
"preview": "vite preview"
},
"dependencies": {
+ "@headlessui/react": "^2.2.4",
+ "@heroicons/react": "^2.2.0",
"axios": "^1.9.0",
+ "bootstrap": "^5.3.6",
+ "framer-motion": "^12.23.0",
+ "lucide-react": "^0.525.0",
"react": "^19.1.0",
+ "react-bootstrap": "^2.10.10",
"react-dom": "^19.1.0",
- "vis-network": "^9.1.12"
+ "react-router-dom": "^7.6.2",
+ "react-select": "^5.10.1",
+ "recharts": "^2.15.3",
+ "zustand": "^5.0.5"
},
"devDependencies": {
"@eslint/js": "^9.25.0",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/react-select": "^5.0.0",
"@vitejs/plugin-react": "^4.4.1",
+ "autoprefixer": "^10.4.21",
"eslint": "^9.25.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^16.0.0",
+ "postcss": "^8.5.5",
+ "tailwindcss": "^4.1.10",
"typescript": "~5.8.3",
"typescript-eslint": "^8.30.1",
"vite": "^6.3.5"
diff --git a/project-alpha/frontend/public/vite.svg b/team-bhavitha-dsarecommender/client/public/vite.svg
similarity index 100%
rename from project-alpha/frontend/public/vite.svg
rename to team-bhavitha-dsarecommender/client/public/vite.svg
diff --git a/team-bhavitha-dsarecommender/client/src/App.css b/team-bhavitha-dsarecommender/client/src/App.css
new file mode 100644
index 000000000..2cc25c53e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/App.css
@@ -0,0 +1,690 @@
+/* client/src/App.css - Enhanced Modern Design */
+
+/* Modern Color Palette */
+:root {
+ --primary-purple: #8b5cf6;
+ --primary-purple-dark: #7c3aed;
+ --primary-purple-light: #a78bfa;
+ --secondary-blue: #3b82f6;
+ --accent-green: #10b981;
+ --accent-orange: #f59e0b;
+ --accent-red: #ef4444;
+ --dark-bg: #0f172a;
+ --dark-card: #1e293b;
+ --dark-border: #334155;
+ --text-primary: #f8fafc;
+ --text-secondary: #cbd5e1;
+ --text-muted: #94a3b8;
+ --gradient-primary: linear-gradient(135deg, #8b5cf6 0%, #3b82f6 100%);
+ --gradient-secondary: linear-gradient(135deg, #1e293b 0%, #334155 100%);
+ --shadow-soft: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ --shadow-medium: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ --shadow-large: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
+}
+
+/* Enhanced Spinner */
+.spinner {
+ border: 3px solid rgba(139, 92, 246, 0.1);
+ border-top: 3px solid var(--primary-purple);
+ border-radius: 50%;
+ width: 24px;
+ height: 24px;
+ animation: spin 1s linear infinite;
+ display: inline-block;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+/* Enhanced Loading Overlay */
+.loading-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, rgba(15, 23, 42, 0.95) 0%, rgba(30, 41, 59, 0.95) 100%);
+ backdrop-filter: blur(10px);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1050;
+ color: var(--text-primary);
+ flex-direction: column;
+}
+
+.loading-overlay .spinner {
+ width: 60px;
+ height: 60px;
+ border-width: 4px;
+ margin-bottom: 20px;
+}
+
+/* Enhanced Body Styles */
+body {
+ background: var(--dark-bg);
+ color: var(--text-primary);
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ line-height: 1.6;
+}
+
+#root {
+ background: var(--dark-bg);
+ color: var(--text-primary);
+ min-height: 100vh;
+}
+
+/* Enhanced Text Colors */
+.text-dark-contrast {
+ color: #1e293b !important;
+}
+
+.text-purple {
+ color: var(--primary-purple) !important;
+}
+
+.text-purple-dark {
+ color: var(--primary-purple-dark) !important;
+}
+
+.text-purple-light {
+ color: var(--primary-purple-light) !important;
+}
+
+/* Enhanced Form Controls */
+.form-control {
+ background-color: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ color: var(--text-primary);
+ border-radius: 12px;
+ padding: 12px 16px;
+ transition: all 0.3s ease;
+}
+
+.form-control:focus {
+ background-color: var(--dark-card);
+ border-color: var(--primary-purple);
+ box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
+ color: var(--text-primary);
+}
+
+.form-control::placeholder {
+ color: var(--text-muted);
+ opacity: 1;
+}
+
+/* Enhanced Buttons */
+.btn {
+ border-radius: 12px;
+ font-weight: 600;
+ padding: 12px 24px;
+ transition: all 0.3s ease;
+ border: none;
+ position: relative;
+ overflow: hidden;
+}
+
+.btn-primary {
+ background: var(--gradient-primary);
+ color: white;
+ box-shadow: var(--shadow-soft);
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-medium);
+ background: linear-gradient(135deg, var(--primary-purple-dark) 0%, var(--secondary-blue) 100%);
+}
+
+.btn-success {
+ background: linear-gradient(135deg, var(--accent-green) 0%, #059669 100%);
+ color: white;
+ box-shadow: var(--shadow-soft);
+}
+
+.btn-success:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-medium);
+ background: linear-gradient(135deg, #059669 0%, #047857 100%);
+}
+
+.btn-warning {
+ background: linear-gradient(135deg, var(--accent-orange) 0%, #d97706 100%);
+ color: white;
+ box-shadow: var(--shadow-soft);
+}
+
+.btn-warning:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-medium);
+ background: linear-gradient(135deg, #d97706 0%, #b45309 100%);
+}
+
+.btn-info {
+ background: linear-gradient(135deg, var(--secondary-blue) 0%, #2563eb 100%);
+ color: white;
+ box-shadow: var(--shadow-soft);
+}
+
+.btn-info:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-medium);
+ background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
+}
+
+/* Enhanced Cards */
+.card {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 16px;
+ box-shadow: var(--shadow-soft);
+ transition: all 0.3s ease;
+ overflow: hidden;
+}
+
+.card:hover {
+ transform: translateY(-4px);
+ box-shadow: var(--shadow-large);
+ border-color: var(--primary-purple);
+}
+
+.card-body {
+ padding: 1.5rem;
+}
+
+/* Enhanced Clickable Elements */
+.clickable-badge {
+ cursor: pointer;
+ transition: all 0.3s ease;
+ border-radius: 20px;
+ padding: 8px 16px;
+ font-weight: 600;
+}
+
+.clickable-badge:hover {
+ background: var(--gradient-primary) !important;
+ color: white !important;
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-medium);
+}
+
+.clickable-card {
+ transition: all 0.3s ease;
+ cursor: pointer;
+}
+
+.clickable-card:hover {
+ transform: translateY(-8px) scale(1.02);
+ box-shadow: var(--shadow-large) !important;
+ border-color: var(--primary-purple) !important;
+}
+
+/* Enhanced Navigation */
+.navbar {
+ background: rgba(15, 23, 42, 0.95) !important;
+ backdrop-filter: blur(20px);
+ border-bottom: 2px solid var(--dark-border);
+ box-shadow: var(--shadow-medium);
+}
+
+.navbar-brand {
+ font-weight: 800;
+ font-size: 1.5rem;
+ background: var(--gradient-primary);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.nav-link {
+ font-weight: 600;
+ transition: all 0.3s ease;
+ border-radius: 8px;
+ padding: 8px 16px !important;
+}
+
+.nav-link:hover {
+ background: rgba(139, 92, 246, 0.1);
+ color: var(--primary-purple) !important;
+}
+
+.active-link {
+ background: var(--gradient-primary) !important;
+ color: white !important;
+ box-shadow: var(--shadow-soft);
+}
+
+/* Enhanced Dropdown */
+.dropdown-menu-dark {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 12px;
+ box-shadow: var(--shadow-large);
+ backdrop-filter: blur(20px);
+}
+
+.dropdown-menu-dark .dropdown-item {
+ color: var(--text-primary);
+ padding: 12px 20px;
+ transition: all 0.3s ease;
+ border-radius: 8px;
+ margin: 4px 8px;
+}
+
+.dropdown-menu-dark .dropdown-item:hover {
+ background: var(--gradient-primary);
+ color: white;
+ transform: translateX(4px);
+}
+
+.dropdown-menu-dark .dropdown-divider {
+ border-top-color: var(--dark-border);
+ margin: 8px 16px;
+}
+
+/* Enhanced Dashboard Sections */
+.dashboard-section {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 20px;
+ padding: 2rem;
+ margin-bottom: 2rem;
+ box-shadow: var(--shadow-soft);
+ transition: all 0.3s ease;
+}
+
+.dashboard-section:hover {
+ border-color: var(--primary-purple);
+ box-shadow: var(--shadow-medium);
+}
+
+/* Enhanced Charts */
+.chart-container {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 16px;
+ padding: 1.5rem;
+ box-shadow: var(--shadow-soft);
+}
+
+/* Enhanced List Groups */
+.list-group-item {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ color: var(--text-primary);
+ border-radius: 12px;
+ margin-bottom: 0.5rem;
+ transition: all 0.3s ease;
+}
+
+.list-group-item:hover {
+ background: rgba(139, 92, 246, 0.1);
+ border-color: var(--primary-purple);
+ transform: translateX(4px);
+}
+
+/* Enhanced Badges */
+.badge {
+ border-radius: 20px;
+ font-weight: 600;
+ padding: 8px 16px;
+ font-size: 0.875rem;
+}
+
+.badge.bg-primary {
+ background: var(--gradient-primary) !important;
+}
+
+.badge.bg-success {
+ background: linear-gradient(135deg, var(--accent-green) 0%, #059669 100%) !important;
+}
+
+.badge.bg-warning {
+ background: linear-gradient(135deg, var(--accent-orange) 0%, #d97706 100%) !important;
+}
+
+/* Enhanced Progress Bars */
+.progress {
+ background: var(--dark-border);
+ border-radius: 12px;
+ height: 12px;
+ overflow: hidden;
+}
+
+.progress-bar {
+ background: var(--gradient-primary);
+ border-radius: 12px;
+ transition: all 0.3s ease;
+}
+
+/* Enhanced Alerts */
+.alert {
+ border-radius: 12px;
+ border: none;
+ padding: 1rem 1.5rem;
+ font-weight: 600;
+}
+
+.alert-primary {
+ background: rgba(139, 92, 246, 0.1);
+ color: var(--primary-purple);
+ border-left: 4px solid var(--primary-purple);
+}
+
+.alert-success {
+ background: rgba(16, 185, 129, 0.1);
+ color: var(--accent-green);
+ border-left: 4px solid var(--accent-green);
+}
+
+.alert-warning {
+ background: rgba(245, 158, 11, 0.1);
+ color: var(--accent-orange);
+ border-left: 4px solid var(--accent-orange);
+}
+
+.alert-danger {
+ background: rgba(239, 68, 68, 0.1);
+ color: var(--accent-red);
+ border-left: 4px solid var(--accent-red);
+}
+
+/* Enhanced Modal */
+.modal-content {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 16px;
+ box-shadow: var(--shadow-large);
+}
+
+.modal-header {
+ border-bottom: 2px solid var(--dark-border);
+ padding: 1.5rem;
+}
+
+.modal-body {
+ padding: 1.5rem;
+}
+
+.modal-footer {
+ border-top: 2px solid var(--dark-border);
+ padding: 1.5rem;
+}
+
+/* Enhanced Tables */
+.table {
+ color: var(--text-primary);
+}
+
+.table-dark {
+ background: var(--dark-card);
+ border-radius: 12px;
+ overflow: hidden;
+}
+
+.table-dark th {
+ background: var(--dark-border);
+ border-color: var(--dark-border);
+ font-weight: 600;
+}
+
+.table-dark td {
+ border-color: var(--dark-border);
+}
+
+/* Enhanced Animations */
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInLeft {
+ from {
+ opacity: 0;
+ transform: translateX(-30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes pulse {
+ 0%, 100% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.05);
+ }
+}
+
+.animate-fade-in-up {
+ animation: fadeInUp 0.6s ease-out;
+}
+
+.animate-slide-in-left {
+ animation: slideInLeft 0.6s ease-out;
+}
+
+.animate-pulse {
+ animation: pulse 2s infinite;
+}
+
+/* Enhanced Scrollbar */
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--dark-border);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--gradient-primary);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--primary-purple-dark);
+}
+
+/* Enhanced Focus States */
+*:focus {
+ outline: 2px solid var(--primary-purple);
+ outline-offset: 2px;
+}
+
+/* Enhanced Responsive Design */
+@media (max-width: 768px) {
+ .card {
+ margin-bottom: 1rem;
+ }
+
+ .btn {
+ width: 100%;
+ margin-bottom: 0.5rem;
+ }
+
+ .dashboard-section {
+ padding: 1rem;
+ }
+}
+
+/* Enhanced Loading States */
+.skeleton {
+ background: linear-gradient(90deg, var(--dark-border) 25%, var(--dark-card) 50%, var(--dark-border) 75%);
+ background-size: 200% 100%;
+ animation: loading 1.5s infinite;
+ border-radius: 8px;
+}
+
+@keyframes loading {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+}
+
+/* Enhanced Tooltips */
+.tooltip {
+ background: var(--dark-card);
+ border: 2px solid var(--dark-border);
+ border-radius: 8px;
+ box-shadow: var(--shadow-medium);
+}
+
+.tooltip-inner {
+ background: var(--dark-card);
+ color: var(--text-primary);
+ border-radius: 6px;
+ padding: 8px 12px;
+}
+
+/* Enhanced Form Validation */
+.form-control.is-valid {
+ border-color: var(--accent-green);
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
+}
+
+.form-control.is-invalid {
+ border-color: var(--accent-red);
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
+}
+
+.valid-feedback {
+ color: var(--accent-green);
+ font-weight: 600;
+}
+
+.invalid-feedback {
+ color: var(--accent-red);
+ font-weight: 600;
+}
+
+/* Enhanced Grid System */
+.row {
+ margin-left: -0.75rem;
+ margin-right: -0.75rem;
+}
+
+.col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+}
+
+/* Enhanced Container */
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 1rem;
+}
+
+/* Enhanced Spacing Utilities */
+.mt-6 { margin-top: 4rem !important; }
+.mb-6 { margin-bottom: 4rem !important; }
+.pt-6 { padding-top: 4rem !important; }
+.pb-6 { padding-bottom: 4rem !important; }
+
+/* Enhanced Border Radius */
+.rounded-xl { border-radius: 1rem !important; }
+.rounded-2xl { border-radius: 1.5rem !important; }
+.rounded-3xl { border-radius: 2rem !important; }
+
+/* Enhanced Shadows */
+.shadow-xl {
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
+}
+
+.shadow-2xl {
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
+}
+
+/* Enhanced Gradients */
+.bg-gradient-primary {
+ background: var(--gradient-primary) !important;
+}
+
+.bg-gradient-secondary {
+ background: var(--gradient-secondary) !important;
+}
+
+/* Enhanced Glass Effect */
+.glass {
+ background: rgba(30, 41, 59, 0.8);
+ backdrop-filter: blur(20px);
+ border: 2px solid rgba(255, 255, 255, 0.1);
+}
+
+/* Enhanced Hover Effects */
+.hover-lift:hover {
+ transform: translateY(-4px);
+ box-shadow: var(--shadow-large);
+}
+
+.hover-scale:hover {
+ transform: scale(1.05);
+}
+
+.hover-glow:hover {
+ box-shadow: 0 0 20px rgba(139, 92, 246, 0.3);
+}
+
+/* Enhanced Text Gradients */
+.text-gradient {
+ background: var(--gradient-primary);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+/* Enhanced Border Gradients */
+.border-gradient {
+ border: 2px solid;
+ border-image: var(--gradient-primary) 1;
+}
+
+/* Enhanced Focus Ring */
+.focus-ring {
+ transition: all 0.3s ease;
+}
+
+.focus-ring:focus {
+ box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.3);
+ outline: none;
+}
+
+/* Enhanced Disabled States */
+.btn:disabled,
+.form-control:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Enhanced Selection */
+::selection {
+ background: var(--primary-purple);
+ color: white;
+}
+
+/* Enhanced Print Styles */
+@media print {
+ .no-print {
+ display: none !important;
+ }
+
+ body {
+ background: white !important;
+ color: black !important;
+ }
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/App.tsx b/team-bhavitha-dsarecommender/client/src/App.tsx
new file mode 100644
index 000000000..f65462ce1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/App.tsx
@@ -0,0 +1,58 @@
+import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
+import LoginPage from "./pages/LoginPage.tsx";
+import Dashboard from './pages/Dashboard';
+import RegisterPage from './pages/RegisterPage';
+import ProtectedRoutes from "./components/ProtectedRoutes";
+import QuizPage from "./pages/QuizPage";
+import QuizSelectPage from "./pages/QuizSelectPage";
+import HomePage from './pages/HomePage';
+import Navbar from './components/Navbar';
+import Footer from './components/Footer';
+import ExploreTopicPage from "./pages/ExploreTopicPage";
+import RecommendationPage from "./pages/RecommendationPage";
+import AppEntry from "./routes/AppEntry";
+import DiscussionDetailPage from "./pages/DiscussionDetailPage";
+import Discuss from './pages/DiscussionPage.tsx';
+import StudentDetailPage from './pages/StudentDetailPage.tsx';
+import PlaygroundPage from './pages/PlaygroundPage.tsx';
+import AskQuestionPage from './pages/AskQuestionPage.tsx';
+import StudentAssignments from './pages/StudentAssignments.tsx';
+
+function App() {
+ return (
+
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+
+ {/* Public routes go here */}
+ {/* Protected routes go here */}
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+
+
+ );
+}
+
+export default App;
\ No newline at end of file
diff --git a/project-alpha/frontend/src/assets/react.svg b/team-bhavitha-dsarecommender/client/src/assets/react.svg
similarity index 100%
rename from project-alpha/frontend/src/assets/react.svg
rename to team-bhavitha-dsarecommender/client/src/assets/react.svg
diff --git a/team-bhavitha-dsarecommender/client/src/components/AssignTaskModal.tsx b/team-bhavitha-dsarecommender/client/src/components/AssignTaskModal.tsx
new file mode 100644
index 000000000..4f33ca7c4
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/AssignTaskModal.tsx
@@ -0,0 +1,105 @@
+import { useState } from "react";
+import { Modal, Form, Button } from "react-bootstrap";
+import { api } from "../lib/api";
+import "./customModal.css";
+interface AssignTaskModalProps {
+ show: boolean;
+ onClose: () => void;
+ username: string;
+ onSuccess?: () => void;
+}
+
+export default function AssignTaskModal({ show, onClose, username, onSuccess }: AssignTaskModalProps) {
+ const [assignmentTitle, setAssignmentTitle] = useState("");
+ const [assignmentDesc, setAssignmentDesc] = useState("");
+ const [file, setFile] = useState(null);
+ const [uploading, setUploading] = useState(false);
+
+ const handleAssign = async () => {
+ if (!assignmentTitle || !assignmentDesc || !file) {
+ alert("All fields are required!");
+ return;
+ }
+
+ try {
+ setUploading(true);
+ const formData = new FormData();
+ formData.append("username", username);
+ formData.append("title", assignmentTitle);
+ formData.append("description", assignmentDesc);
+ formData.append("file", file);
+
+ await api.post("/assignments", formData, {
+ headers: { "Content-Type": "multipart/form-data" },
+ });
+
+ alert("Task assigned successfully!");
+ onClose();
+ setAssignmentTitle("");
+ setAssignmentDesc("");
+ setFile(null);
+ onSuccess?.();
+ } catch (err) {
+ console.error(err);
+ alert("Failed to assign task.");
+ } finally {
+ setUploading(false);
+ }
+ };
+
+ return (
+
+
+ Assign Task to {username}
+
+
+
+
+ Title
+ setAssignmentTitle(e.target.value)}
+ placeholder="Assignment title"
+ />
+
+
+
+ Description
+ setAssignmentDesc(e.target.value)}
+ placeholder="Describe the task..."
+ />
+
+
+
+ Upload File (PDF/Image)
+ ) => {
+ const selectedFile = e.target.files?.[0];
+ if (selectedFile) {
+ setFile(selectedFile);
+ }
+ }}
+ />
+
+
+
+
+
+
+ Cancel
+
+
+ {uploading ? "Uploading..." : "Assign"}
+
+
+
+ );
+}
diff --git a/team-bhavitha-dsarecommender/client/src/components/AttemptHistory.tsx b/team-bhavitha-dsarecommender/client/src/components/AttemptHistory.tsx
new file mode 100644
index 000000000..e77943aab
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/AttemptHistory.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+
+type Props = {
+ history: Record;
+};
+
+const AttemptHistory = ({ history }: Props) => {
+ if (Object.keys(history).length === 0)
+ return Play and Know...
;
+
+ return (
+
+ {Object.entries(history).map(([concept, result]) => (
+
+
{concept}
+
+ Strong: {result.strongConcepts.join(", ") || "None"}
+
+
+ Weak: {result.weakConcepts.join(", ") || "None"}
+
+
+ Recommended: {result.recommendedConcepts.join(", ") || "None"}
+
+
+ ))}
+
+ );
+};
+
+export default AttemptHistory;
diff --git a/team-bhavitha-dsarecommender/client/src/components/DashboardBackground.tsx b/team-bhavitha-dsarecommender/client/src/components/DashboardBackground.tsx
new file mode 100644
index 000000000..3c7b32f68
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/DashboardBackground.tsx
@@ -0,0 +1,12 @@
+// components/DashboardBackground.tsx
+import Dashboard from "../pages/Dashboard";
+
+const DashboardBackground = () => {
+ return (
+
+
+
+ );
+};
+
+export default DashboardBackground;
diff --git a/team-bhavitha-dsarecommender/client/src/components/DiscussModal.tsx b/team-bhavitha-dsarecommender/client/src/components/DiscussModal.tsx
new file mode 100644
index 000000000..c6f07be14
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/DiscussModal.tsx
@@ -0,0 +1,125 @@
+// src/components/StartDiscussionModal.tsx
+import { useState } from "react";
+import { Modal, Button, Form } from "react-bootstrap";
+import { api } from "../lib/api";
+import "./customModal.css"; // Make sure this is imported
+
+interface Props {
+ show: boolean;
+ onClose: () => void;
+ onRefresh: () => void;
+ username: string;
+ userRole?: string;
+}
+
+const StartDiscussionModal = ({ show, onClose, onRefresh, username }: Props) => {
+ const [type, setType] = useState<"general" | "question">("general");
+ const [text, setText] = useState("");
+ const [topic, setTopic] = useState("");
+ const [questionIndex, setQuestionIndex] = useState("");
+ const [questionText, setQuestionText] = useState("");
+
+ const handleSubmit = async () => {
+ try {
+ if (type === "general") {
+ await api.post("/discuss/general", { username, text });
+ } else {
+ await api.post("/discuss/create-or-get", {
+ topic,
+ questionIndex: Number(questionIndex),
+ questionText,
+ username,
+ });
+ }
+ onRefresh();
+ onClose();
+ } catch (err) {
+ console.error("Failed to create discussion", err);
+ alert("Failed to create discussion");
+ }
+ };
+
+ return (
+
+
+ Start a Discussion
+
+
+ setType("general")}
+ className="discussion-radio"
+ />
+ setType("question")}
+ className="discussion-radio mb-3"
+ />
+
+ {type === "general" ? (
+
+ Message
+ setText(e.target.value)}
+ className="form-control-dark"
+ placeholder="What's on your mind?"
+ />
+
+ ) : (
+ <>
+
+ Topic
+ setTopic(e.target.value)}
+ className="form-control-dark"
+ placeholder="e.g., Graph Theory"
+ />
+
+
+ Question Index
+
+ setQuestionIndex(e.target.value === "" ? "" : Number(e.target.value))
+ }
+ className="form-control-dark"
+ />
+
+
+ Question Text
+ setQuestionText(e.target.value)}
+ className="form-control-dark"
+ />
+
+ >
+ )}
+
+
+
+
+ Cancel
+
+
+ Create
+
+
+
+ );
+};
+
+export default StartDiscussionModal;
diff --git a/team-bhavitha-dsarecommender/client/src/components/Footer.tsx b/team-bhavitha-dsarecommender/client/src/components/Footer.tsx
new file mode 100644
index 000000000..a80a4ce58
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/Footer.tsx
@@ -0,0 +1,242 @@
+import { motion } from 'framer-motion';
+import { Heart, Github, Linkedin, Mail, BookOpen } from 'lucide-react';
+
+const Footer = () => {
+ const currentYear = new Date().getFullYear();
+
+ const containerVariants = {
+ hidden: { opacity: 0, y: 50 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6,
+ ease: "easeOut" as const,
+ staggerChildren: 0.1
+ }
+ }
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
LearnFlow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Features
+
+
+
+ Personalized Learning
+
+
+
+
+ Adaptive Quizzes
+
+
+
+
+ Progress Tracking
+
+
+
+
+ Knowledge Graph
+
+
+
+
+
+
+ Resources
+
+
+
+ Documentation
+
+
+
+
+ API Reference
+
+
+
+
+ Tutorials
+
+
+
+
+ Support
+
+
+
+
+
+
+ Company
+
+
+
+ About Us
+
+
+
+
+ Careers
+
+
+
+
+ Privacy Policy
+
+
+
+
+ Terms of Service
+
+
+
+
+
+
+ Stats
+
+
+
+
+
+
+
+
+ Β© {currentYear} LearnFlow. All rights reserved.
+
+
+
+
+
+
+
+ );
+};
+
+export default Footer;
diff --git a/server/.gitkeep b/team-bhavitha-dsarecommender/client/src/components/HeroSection.tsx
similarity index 100%
rename from server/.gitkeep
rename to team-bhavitha-dsarecommender/client/src/components/HeroSection.tsx
diff --git a/team-bhavitha-dsarecommender/client/src/components/LearnedConceptCard.tsx b/team-bhavitha-dsarecommender/client/src/components/LearnedConceptCard.tsx
new file mode 100644
index 000000000..a2bda5db6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/LearnedConceptCard.tsx
@@ -0,0 +1,135 @@
+// client/src/components/LearnedConceptCard.tsx
+import React from 'react';
+import { BookOpen, Code, FlaskConical, Calculator, BrainCircuit, Lightbulb, GraduationCap, CheckCircle, TrendingUp, Award } from 'lucide-react';
+import { motion } from 'framer-motion';
+
+interface LearnedConceptCardProps {
+ title: string;
+ quizScores?: { score: number; date: string }[];
+}
+
+// A simple map for topic-to-icon. Expand this as needed.
+const topicIcons: { [key: string]: React.ElementType } = {
+ 'Python Basics': Code,
+ 'Data Structures': BrainCircuit,
+ 'Algorithms': Lightbulb,
+ 'Calculus': Calculator,
+ 'Chemistry': FlaskConical,
+ 'Physics': GraduationCap,
+ // Add more mappings for your validTopics
+};
+
+const LearnedConceptCard = ({ title, quizScores }: LearnedConceptCardProps) => {
+ const IconComponent = topicIcons[title] || BookOpen;
+ const lastScore = quizScores && quizScores.length > 0 ? quizScores[quizScores.length - 1].score : null;
+
+ const cardVariants = {
+ hidden: { opacity: 0, scale: 0.9, y: 20 },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ },
+ hover: {
+ scale: 1.05,
+ y: -8,
+ transition: {
+ duration: 0.3,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ const iconVariants = {
+ hover: {
+ rotate: 360,
+ scale: 1.1,
+ transition: {
+ duration: 0.6,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ const getScoreColor = (score: number) => {
+ if (score >= 90) return "text-success";
+ if (score >= 80) return "text-warning";
+ if (score >= 70) return "text-info";
+ return "text-secondary";
+ };
+
+ const getScoreIcon = (score: number) => {
+ if (score >= 90) return Award;
+ if (score >= 80) return TrendingUp;
+ return CheckCircle;
+ };
+
+ return (
+
+
+
+
+
+
+
+
{title}
+
+
+
+ Completed
+
+
+ {lastScore && (
+
+
+ {React.createElement(getScoreIcon(lastScore), { size: 16, className: "me-2" })}
+ Last Score: {lastScore.toFixed(0)}%
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ );
+};
+
+export default LearnedConceptCard;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/components/LoadingSpinner.tsx b/team-bhavitha-dsarecommender/client/src/components/LoadingSpinner.tsx
new file mode 100644
index 000000000..0e6f68d6a
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/LoadingSpinner.tsx
@@ -0,0 +1,52 @@
+// client/src/components/LoadingSpinner.tsx
+import { motion } from 'framer-motion';
+import { Loader2 } from 'lucide-react';
+
+interface LoadingSpinnerProps {
+ size?: "sm" | "md" | "lg";
+ text?: string;
+ className?: string;
+ message?:string;
+}
+
+const LoadingSpinner = ({ size = "md", text, className = "" }: LoadingSpinnerProps) => {
+ const sizeMap = {
+ sm: 16,
+ md: 24,
+ lg: 32
+ };
+
+ const spinnerVariants = {
+ animate: {
+ rotate: 360,
+ transition: {
+ duration: 1,
+ repeat: Infinity,
+ ease: "linear" as const
+ }
+ }
+ };
+
+ return (
+
+
+
+
+ {text && (
+
+ {text}
+
+ )}
+
+ );
+};
+
+export default LoadingSpinner;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/components/LoadingWithQuotes.tsx b/team-bhavitha-dsarecommender/client/src/components/LoadingWithQuotes.tsx
new file mode 100644
index 000000000..94cfda8eb
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/LoadingWithQuotes.tsx
@@ -0,0 +1,37 @@
+import { useEffect, useState } from "react";
+
+interface LoadingWithQuoteProps {
+ quotes?: string[];
+ intervalMs?: number;
+}
+
+const defaultQuotes = [
+ "Why did the Python list break up with the array? Too much indexing drama!",
+ "Recursion in Python: It's like calling yourself until you believe it.",
+ "DSA in Python: When time complexity meets duck typing.",
+ "Why do Python coders love trees? Because they always branch out.",
+];
+
+const LoadingWithQuote = ({ quotes = defaultQuotes, intervalMs = 3000 }: LoadingWithQuoteProps) => {
+ const [quoteIndex, setQuoteIndex] = useState(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setQuoteIndex((prev) => (prev + 1) % quotes.length);
+ }, intervalMs);
+
+ return () => clearInterval(interval);
+ }, [quotes.length, intervalMs]);
+
+ return (
+
+
+
{quotes[quoteIndex]}
+
+ );
+};
+
+export default LoadingWithQuote;
diff --git a/team-bhavitha-dsarecommender/client/src/components/Navbar.tsx b/team-bhavitha-dsarecommender/client/src/components/Navbar.tsx
new file mode 100644
index 000000000..fbc2bdcb9
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/Navbar.tsx
@@ -0,0 +1,247 @@
+import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
+import { useAuthStore } from "../store/authStore";
+import { useUserStore } from "../store/userStore";
+import { UserCircle, LogOut, Home, BookOpen, Target, MessageCircle, Upload, BarChart3 } from "lucide-react";
+import { motion } from "framer-motion";
+
+const Navbar = () => {
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
+ const logout = useAuthStore((state) => state.logout);
+ const username = useUserStore((state) => state.username);
+ const role = useUserStore((state) => state.role);
+ const navigate = useNavigate();
+ const location = useLocation();
+
+ const handleLogout = () => {
+ logout();
+ navigate("/");
+ };
+
+ const protectedLink = (path: string) =>
+ isAuthenticated ? path : "/register";
+
+ const brandLink = isAuthenticated
+ ? role === "educator"
+ ? "/dashboard"
+ : `/dashboard/${username}`
+ : "/";
+
+ const navItemVariants = {
+ hidden: { opacity: 0, y: -10 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.3,
+ ease: "easeOut" as const
+ }
+ },
+ hover: {
+ y: -2,
+ transition: {
+ duration: 0.2,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+
+
+
+
+ LearnFlow
+
+
+
+
+
+
+
+
+
+ {isAuthenticated && role === "educator" ? (
+ <>
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Dashboard
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Discussions
+
+
+ >
+ ) : isAuthenticated ? (
+ <>
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${
+ isActive || location.pathname === `/dashboard` ? "active-link" : ""
+ }`
+ }
+ >
+
+ Dashboard
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Take Quiz
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Get Recommendation
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Ask Dhruv
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+
+ Discuss
+
+
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+ Assignments
+
+
+ >
+ ) : (
+ <>
+
+
+ `nav-link text-white fw-semibold mx-2 d-flex align-items-center ${isActive ? "active-link" : ""}`
+ }
+ >
+ Sign In
+
+
+
+
+ Sign Up
+
+
+ >
+ )}
+
+ {isAuthenticated && (
+
+
+
+ {username}
+
+
+
+
+
+ Dashboard
+
+
+
+
+
+
+ Logout
+
+
+
+
+ )}
+
+
+
+
+ );
+};
+
+export default Navbar;
diff --git a/team-bhavitha-dsarecommender/client/src/components/NewThreadForm.tsx b/team-bhavitha-dsarecommender/client/src/components/NewThreadForm.tsx
new file mode 100644
index 000000000..5340b2803
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/NewThreadForm.tsx
@@ -0,0 +1,52 @@
+// src/components/NewThreadForm.tsx
+import { useState } from "react";
+import { api } from "../lib/api";
+import { useUserStore } from "../store/userStore";
+
+const NewThreadForm = ({ onNewThread }: { onNewThread: (t: any) => void }) => {
+ const [title, setTitle] = useState("");
+ const [content, setContent] = useState("");
+ const username = useUserStore((state) => state.username);
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ try {
+ const res = await api.post("/discuss/general", {
+ title,
+ createdBy: username,
+ content,
+ });
+ onNewThread(res.data);
+ setTitle("");
+ setContent("");
+ } catch (err) {
+ console.error("Failed to create thread:", err);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default NewThreadForm;
diff --git a/team-bhavitha-dsarecommender/client/src/components/ProtectedRoutes.tsx b/team-bhavitha-dsarecommender/client/src/components/ProtectedRoutes.tsx
new file mode 100644
index 000000000..995eb5ef0
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/ProtectedRoutes.tsx
@@ -0,0 +1,9 @@
+import { Navigate, Outlet } from "react-router-dom";
+import { useAuthStore } from "../store/authStore";
+
+const ProtectedRoute = () => {
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
+ return isAuthenticated ? : ;
+};
+
+export default ProtectedRoute;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/components/QuizCard.tsx b/team-bhavitha-dsarecommender/client/src/components/QuizCard.tsx
new file mode 100644
index 000000000..91e8be39f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/QuizCard.tsx
@@ -0,0 +1,119 @@
+// client/src/components/QuizCard.tsx
+import LoadingSpinner from "./LoadingSpinner";
+import { motion } from "framer-motion";
+import { Target, Play } from "lucide-react";
+
+interface QuizCardProps {
+ topic: string;
+ onTakeQuiz: (topic: string) => void;
+ isLoading?: boolean;
+}
+
+const QuizCard = ({ topic, onTakeQuiz, isLoading }: QuizCardProps) => {
+ const cardVariants = {
+ hidden: { opacity: 0, scale: 0.9, y: 20 },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ },
+ hover: {
+ scale: 1.05,
+ y: -8,
+ transition: {
+ duration: 0.3,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ const buttonVariants = {
+ hover: {
+ scale: 1.05,
+ transition: {
+ duration: 0.2,
+ ease: "easeOut" as const
+ }
+ },
+ tap: {
+ scale: 0.95,
+ transition: {
+ duration: 0.1,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+ !isLoading && onTakeQuiz(topic)}
+ style={{ cursor: isLoading ? "not-allowed" : "pointer" }}
+ >
+
+
+
+
+
+
{topic}
+
+ Test your knowledge and track your progress
+
+
+
+
+ {
+ e.stopPropagation();
+ onTakeQuiz(topic);
+ }}
+ className="btn btn-primary w-100 d-flex align-items-center justify-content-center"
+ disabled={isLoading}
+ whileHover={{ scale: 1.02 }}
+ whileTap={{ scale: 0.98 }}
+ >
+ {isLoading ? (
+
+
+ Loading...
+
+ ) : (
+
+ )}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default QuizCard;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/components/ThreadCard.tsx b/team-bhavitha-dsarecommender/client/src/components/ThreadCard.tsx
new file mode 100644
index 000000000..984eeae41
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/ThreadCard.tsx
@@ -0,0 +1,22 @@
+// src/components/ThreadCard.tsx
+import { useNavigate } from "react-router-dom";
+
+const ThreadCard = ({ thread }: { thread: any }) => {
+ const navigate = useNavigate();
+
+ return (
+
+
{thread.title}
+
Started by {thread.createdBy}
+
{thread.comments?.[0]?.content}
+
navigate(`/discussion/thread/${thread._id}`)}
+ className="btn btn-outline-primary btn-sm mt-2"
+ >
+ View Thread
+
+
+ );
+};
+
+export default ThreadCard;
diff --git a/team-bhavitha-dsarecommender/client/src/components/customModal.css b/team-bhavitha-dsarecommender/client/src/components/customModal.css
new file mode 100644
index 000000000..0c07fd3cc
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/components/customModal.css
@@ -0,0 +1,31 @@
+/* src/components/customModal.css */
+
+.custom-modal .modal-content {
+ background-color: #1e293b; /* dark slate */
+ color: #f8fafc; /* light text */
+ border-radius: 10px;
+}
+
+.custom-modal .modal-title-text {
+ color: #f1f5f9;
+ font-weight: 600;
+}
+
+.custom-modal .form-label-custom {
+ color: #f1f5f9;
+}
+
+.form-control-dark {
+ background-color: #0f172a; /* very dark background */
+ color: #f1f5f9;
+ border: 2px solid #0d6efd;
+ border-radius: 8px;
+}
+
+.discussion-radio {
+ background-color: #1e293b;
+ color: #f1f5f9;
+ border: 1px solid #0d6efd;
+ padding: 10px;
+ border-radius: 5px;
+}
diff --git a/team-bhavitha-dsarecommender/client/src/data/validTopic.ts b/team-bhavitha-dsarecommender/client/src/data/validTopic.ts
new file mode 100644
index 000000000..19799a5af
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/data/validTopic.ts
@@ -0,0 +1,15 @@
+// src/data/validTopics.ts
+export const validTopics = [
+ "Computation", "Algorithms", "Problem Solving",
+ "Conditionals", "Loops", "Control Flow",
+ "String Manipulation", "Guess and Check", "Approximation", "Bisection Search",
+ "Decomposition", "Abstraction", "Functions",
+ "Tuples", "Lists", "Aliasing", "Mutability", "Cloning",
+ "Recursion", "Dictionaries",
+ "Testing", "Debugging", "Exceptions", "Assertions",
+ "Classes", "OOP", "Encapsulation",
+ "Inheritance", "Subclasses", "Class Hierarchies",
+ "Big-O Notation", "Efficiency", "Space Complexity",
+ "Search Algorithms", "Sorting Algorithms","Complexity Analysis"
+];
+
diff --git a/team-bhavitha-dsarecommender/client/src/hooks/useSyncLearnedTopics.ts b/team-bhavitha-dsarecommender/client/src/hooks/useSyncLearnedTopics.ts
new file mode 100644
index 000000000..465066746
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/hooks/useSyncLearnedTopics.ts
@@ -0,0 +1,23 @@
+import { useEffect } from "react";
+import { useUserStore } from "../store/userStore";
+
+export function useSyncLearnedTopics() {
+ const quizHistory = useUserStore((state) => state.quizHistory);
+ const progress = useUserStore((state) => state.progress);
+ const addLearnedTopic = useUserStore((state) => state.addLearnedTopic);
+
+ useEffect(() => {
+ if (!quizHistory) return;
+
+ quizHistory.forEach((entry: any) => {
+ if (
+ entry.topic &&
+ typeof entry.mastery === "number" &&
+ entry.mastery >= 0.7 &&
+ !progress.includes(entry.topic)
+ ) {
+ addLearnedTopic(entry.topic);
+ }
+ });
+ }, [quizHistory, progress, addLearnedTopic]);
+}
diff --git a/team-bhavitha-dsarecommender/client/src/index.css b/team-bhavitha-dsarecommender/client/src/index.css
new file mode 100644
index 000000000..10683b3f7
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/index.css
@@ -0,0 +1,302 @@
+/* Import Google Fonts */
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
+
+:root {
+ font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.6;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ /* Removed specific colors as Bootstrap will handle most of this */
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* index.css - minimal, primarily for global overrides or resets not covered by Bootstrap */
+body {
+ margin: 0;
+ min-width: 320px;
+ min-height: 100vh;
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+
+/* Smooth scrolling */
+html {
+ scroll-behavior: smooth;
+}
+
+/* Better focus indicators for accessibility */
+*:focus-visible {
+ outline: 2px solid var(--primary-purple);
+ outline-offset: 2px;
+}
+
+/* Improved selection colors */
+::selection {
+ background: var(--primary-purple);
+ color: white;
+}
+
+/* Custom scrollbar for webkit browsers */
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--dark-border);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--gradient-primary);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--primary-purple-dark);
+}
+
+/* Prevent horizontal scroll on mobile */
+html, body {
+ overflow-x: hidden;
+}
+
+/* Better text rendering */
+* {
+ text-rendering: optimizeLegibility;
+ -webkit-font-feature-settings: "kern" 1;
+ font-feature-settings: "kern" 1;
+}
+
+/* Improved button focus states */
+.btn:focus {
+ box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.3);
+}
+
+/* Better form control focus states */
+.form-control:focus {
+ box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
+}
+
+/* Improved card hover effects */
+.card {
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+/* Better animation performance */
+* {
+ will-change: auto;
+}
+
+/* Improved loading states */
+.loading {
+ position: relative;
+ overflow: hidden;
+}
+
+.loading::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ rgba(255, 255, 255, 0.1),
+ transparent
+ );
+ animation: loading-shimmer 1.5s infinite;
+}
+
+@keyframes loading-shimmer {
+ 0% {
+ left: -100%;
+ }
+ 100% {
+ left: 100%;
+ }
+}
+
+/* Better responsive typography */
+@media (max-width: 768px) {
+ html {
+ font-size: 14px;
+ }
+}
+
+@media (min-width: 1200px) {
+ html {
+ font-size: 16px;
+ }
+}
+
+/* Improved print styles */
+@media print {
+ * {
+ background: transparent !important;
+ color: black !important;
+ box-shadow: none !important;
+ text-shadow: none !important;
+ }
+
+ .no-print {
+ display: none !important;
+ }
+}
+
+/* Better mobile touch targets */
+@media (max-width: 768px) {
+ .btn {
+ min-height: 44px;
+ min-width: 44px;
+ }
+
+ .nav-link {
+ padding: 12px 16px !important;
+ }
+}
+
+/* Improved dark mode support */
+@media (prefers-color-scheme: dark) {
+ :root {
+ color-scheme: dark;
+ }
+}
+
+/* Better animation performance for transforms */
+.gpu-accelerated {
+ transform: translateZ(0);
+ backface-visibility: hidden;
+ perspective: 1000px;
+}
+
+/* Improved loading animations */
+.fade-in {
+ animation: fadeIn 0.6s ease-out;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* Better hover effects */
+.hover-lift {
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.hover-lift:hover {
+ transform: translateY(-4px);
+}
+
+/* Improved focus management */
+.focus-visible {
+ outline: 2px solid var(--primary-purple);
+ outline-offset: 2px;
+}
+
+/* Better accessibility */
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+}
+
+/* Improved form validation styles */
+.form-control.is-valid {
+ border-color: var(--accent-green);
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
+}
+
+.form-control.is-invalid {
+ border-color: var(--accent-red);
+ box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
+}
+
+/* Better button states */
+.btn:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Improved modal backdrop */
+.modal-backdrop {
+ backdrop-filter: blur(10px);
+}
+
+/* Better tooltip positioning */
+.tooltip {
+ z-index: 1070;
+}
+
+/* Improved dropdown positioning */
+.dropdown-menu {
+ z-index: 1000;
+}
+
+/* Better responsive images */
+.img-fluid {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Improved text truncation */
+.text-truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* Better responsive utilities */
+@media (max-width: 576px) {
+ .container {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ }
+}
+
+/* Improved animation performance */
+.animate-on-scroll {
+ opacity: 0;
+ transform: translateY(30px);
+ transition: all 0.6s ease-out;
+}
+
+.animate-on-scroll.animated {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+/* Better loading states */
+.skeleton {
+ background: linear-gradient(90deg, var(--dark-border) 25%, var(--dark-card) 50%, var(--dark-border) 75%);
+ background-size: 200% 100%;
+ animation: loading 1.5s infinite;
+ border-radius: 8px;
+}
+
+@keyframes loading {
+ 0% {
+ background-position: 200% 0;
+ }
+ 100% {
+ background-position: -200% 0;
+ }
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/lib/api.ts b/team-bhavitha-dsarecommender/client/src/lib/api.ts
new file mode 100644
index 000000000..36f05914f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/lib/api.ts
@@ -0,0 +1,11 @@
+import axios from 'axios';
+
+ export const api = axios.create({
+ baseURL: import.meta.env.VITE_API_BASE_URL|| "http://localhost:5000/api", // Default to local server if env variable is not set
+ withCredentials: true, // if cookies are used
+});
+export const authApi = axios.create({
+ baseURL: import.meta.env.VITE_AUTH_API_BASE_URL || "http://localhost:5000/api", // Default to local server if env variable is not set
+ withCredentials: true, // if cookies are used
+});
+
diff --git a/project-alpha/frontend/src/main.tsx b/team-bhavitha-dsarecommender/client/src/main.tsx
similarity index 70%
rename from project-alpha/frontend/src/main.tsx
rename to team-bhavitha-dsarecommender/client/src/main.tsx
index bef5202a3..0e858f5c6 100644
--- a/project-alpha/frontend/src/main.tsx
+++ b/team-bhavitha-dsarecommender/client/src/main.tsx
@@ -1,10 +1,12 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
+import './App.css' // Keep this, even if empty, as per your request
import App from './App.tsx'
+import React from 'react';
createRoot(document.getElementById('root')!).render(
,
-)
+);
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/AskQuestionPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/AskQuestionPage.tsx
new file mode 100644
index 000000000..ffc7ad636
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/AskQuestionPage.tsx
@@ -0,0 +1,77 @@
+// src/pages/AskQuestionPage.tsx
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useUserStore } from "../store/userStore";
+import {api} from "../lib/api";
+import {validTopics} from "../data/validTopic";
+
+export default function AskQuestionPage() {
+ const [title, setTitle] = useState("");
+ const [body, setBody] = useState("");
+ const [topic, setTopic] = useState("");
+ const [loading, setLoading] = useState(false);
+ const navigate = useNavigate();
+ const user = useUserStore((state) => state.username);
+
+ const handleSubmit = async () => {
+ if (!title || !body || !topic) {
+ alert("All fields are required.");
+ return;
+ }
+
+ try {
+ setLoading(true);
+ const res = await api.post("/discuss/ask", {
+ userId: user,
+ title,
+ body,
+ topic,
+ });
+ navigate(`/discuss/${res.data.threadId}`);
+ } catch (err) {
+ console.error(err);
+ alert("Failed to post question.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
Ask a Question
+
+ setTitle(e.target.value)}
+ />
+
+ setBody(e.target.value)}
+ />
+
+ setTopic(e.target.value)}
+ >
+ Select related topic
+ {validTopics.map((t) => (
+ {t}
+ ))}
+
+
+
+ {loading ? "Posting..." : "Submit Question"}
+
+
+ );
+}
diff --git a/team-bhavitha-dsarecommender/client/src/pages/Dashboard.tsx b/team-bhavitha-dsarecommender/client/src/pages/Dashboard.tsx
new file mode 100644
index 000000000..c723b6039
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/Dashboard.tsx
@@ -0,0 +1,448 @@
+// import { useEffect, useState } from "react";
+// import { useNavigate } from "react-router-dom";
+// import { api } from "../lib/api";
+// import { useUserStore } from "../store/userStore";
+// import LearnedConceptCard from "../components/LearnedConceptCard";
+// import { LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer } from "recharts";
+
+// // Reuse from your previous file
+// interface QuizHistoryEntry {
+// topic: string;
+// score: number;
+// mastery: number;
+// createdAt: string;
+// }
+
+// interface DashboardProps {
+// asBackground?: boolean;
+// }
+
+// const Dashboard = ({ asBackground = false }: DashboardProps) => {
+// const username = useUserStore((state) => state.username);
+// const role = useUserStore((state) => state.role);
+// const mastery = useUserStore((state) => state.mastery);
+// const progress = useUserStore((state) => state.progress);
+// const quizHistory = useUserStore((state) => state.quizHistory);
+// const setQuizHistory = useUserStore((state) => state.setQuizHistory);
+// const setProfile = useUserStore((state) => state.setProfile);
+// const addLearnedTopic = useUserStore((state) => state.addLearnedTopic);
+// const removeLearnedTopic = useUserStore((state) => state.removeLearnedTopic);
+
+// const navigate = useNavigate();
+
+// const getQuizScoresForTopic = (topic: string) => {
+// return quizHistory
+// .filter((entry) => entry.topic === topic)
+// .map((entry) => ({ score: entry.score, date: entry.createdAt }))
+// .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
+// };
+
+// useEffect(() => {
+// const fetchHistory = async () => {
+// try {
+// const res = await api.get(`/quiz-history/${username}`);
+// if (Array.isArray(res.data)) {
+// setQuizHistory(res.data);
+
+// const topicScoresMap: Record = {};
+// res.data.forEach((entry: QuizHistoryEntry) => {
+// if (!topicScoresMap[entry.topic]) topicScoresMap[entry.topic] = [];
+// topicScoresMap[entry.topic].push(entry.mastery);
+// });
+
+// const updatedMastery: Record = {};
+// Object.entries(topicScoresMap).forEach(([topic, scores]) => {
+// const avg = scores.reduce((a, b) => a + b, 0) / scores.length;
+// updatedMastery[topic] = avg;
+
+// const confidencePercentage = (1 - avg) * 100;
+// const isLearned = progress.includes(topic);
+// if (confidencePercentage >= 70 && !isLearned) {
+// addLearnedTopic(topic);
+// } else if (confidencePercentage < 70 && isLearned) {
+// removeLearnedTopic(topic);
+// }
+// });
+
+// setProfile({ mastery: updatedMastery });
+// }
+// } catch (err) {
+// console.error("Failed to fetch quiz history", err);
+// setQuizHistory([]);
+// }
+// };
+
+// if (username) fetchHistory();
+// }, [username, setQuizHistory, setProfile, progress, addLearnedTopic, removeLearnedTopic]);
+
+// const chartData = quizHistory
+// .map((entry) => ({
+// topic: entry.topic,
+// mastery: (1 - entry.mastery) * 100,
+// date: new Date(entry.createdAt).toLocaleDateString(),
+// fullDate: new Date(entry.createdAt).getTime(),
+// }))
+// .sort((a, b) => a.fullDate - b.fullDate);
+
+// return (
+//
+// {!asBackground && (
+// <>
+//
Welcome, {username}!
+//
+// {role === "educator"
+// ? "Monitor student progress and engage in discussions."
+// : "This is your personalized learning dashboard."}
+//
+// >
+// )}
+
+// {role === "educator" ? (
+// <>
+// {/* Educator View */}
+//
+//
+//
π Student Discussions
+//
This section will show discussions students started. You can reply.
+//
+
+//
+//
+//
π Student Performance
+//
You will be able to search for students and see their quiz & mastery stats.
+//
+
+//
+//
+//
π Topic Suggestions
+//
You can suggest topics to students based on their performance.
+//
+// >
+// ) : (
+// <>
+// {/* Student View */}
+//
+//
+//
Mastery Over Time
+// {chartData.length === 0 ? (
+//
No data available yet to show mastery progression.
+// ) : (
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+// )}
+//
+
+//
+//
+//
Current Mastery Levels
+// {Object.keys(mastery).length === 0 ? (
+//
No mastery data available. Take some quizzes to get started!
+// ) : (
+//
+// {Object.entries(mastery).map(([topic, score]) => (
+//
+// {topic}
+// {(1 - score).toFixed(2)} Confidence
+//
+// ))}
+//
+// )}
+//
+
+//
+//
+//
Topics Learned
+//
+// {progress.length === 0 ? (
+//
No topics marked as completed yet. Keep learning!
+// ) : (
+// progress.map((topic) => (
+//
+//
+//
+// ))
+// )}
+//
+//
+
+//
+//
+//
Quiz History
+// {quizHistory.length === 0 ? (
+//
No quiz attempts recorded yet.
+// ) : (
+//
+// {quizHistory.map((entry, i) => (
+//
+//
+// {entry.topic} β Score: {entry.score}% β Mastery Weight: {entry.mastery}
+//
+// {new Date(entry.createdAt).toLocaleString()}
+//
+//
+// ))}
+//
+// )}
+//
+// >
+// )}
+//
+// );
+// };
+
+// export default Dashboard;
+import { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { api } from "../lib/api";
+import { useUserStore } from "../store/userStore";
+import LearnedConceptCard from "../components/LearnedConceptCard";
+import { LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer } from "recharts";
+
+interface QuizHistoryEntry {
+ topic: string;
+ score: number;
+ mastery: number;
+ createdAt: string;
+}
+
+interface DashboardProps {
+ asBackground?: boolean;
+}
+
+interface Student {
+ username: string;
+ lastActive: string;
+}
+
+const Dashboard = ({ asBackground = false }: DashboardProps) => {
+ const username = useUserStore((state) => state.username);
+ const role = useUserStore((state) => state.role);
+ const mastery = useUserStore((state) => state.mastery);
+ const progress = useUserStore((state) => state.progress);
+ const quizHistory = useUserStore((state) => state.quizHistory);
+ const setQuizHistory = useUserStore((state) => state.setQuizHistory);
+ const setProfile = useUserStore((state) => state.setProfile);
+ const addLearnedTopic = useUserStore((state) => state.addLearnedTopic);
+ const removeLearnedTopic = useUserStore((state) => state.removeLearnedTopic);
+
+ const [students, setStudents] = useState([]);
+
+ const navigate = useNavigate();
+
+ const getQuizScoresForTopic = (topic: string) => {
+ return quizHistory
+ .filter((entry) => entry.topic === topic)
+ .map((entry) => ({ score: entry.score, date: entry.createdAt }))
+ .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
+ };
+
+ useEffect(() => {
+ const fetchHistory = async () => {
+ try {
+ const res = await api.get(`/quiz-history/${username}`);
+ if (Array.isArray(res.data)) {
+ setQuizHistory(res.data);
+
+ const topicScoresMap: Record = {};
+ res.data.forEach((entry: QuizHistoryEntry) => {
+ if (!topicScoresMap[entry.topic]) topicScoresMap[entry.topic] = [];
+ topicScoresMap[entry.topic].push(entry.mastery);
+ });
+
+ const updatedMastery: Record = {};
+ Object.entries(topicScoresMap).forEach(([topic, scores]) => {
+ const avg = scores.reduce((a, b) => a + b, 0) / scores.length;
+ updatedMastery[topic] = avg;
+
+ const confidencePercentage = (1 - avg) * 100;
+ const isLearned = progress.includes(topic);
+ if (confidencePercentage >= 70 && !isLearned) {
+ addLearnedTopic(topic);
+ } else if (confidencePercentage < 70 && isLearned) {
+ removeLearnedTopic(topic);
+ }
+ });
+
+ setProfile({ mastery: updatedMastery });
+ }
+ } catch (err) {
+ console.error("Failed to fetch quiz history", err);
+ setQuizHistory([]);
+ }
+ };
+
+ const fetchStudents = async () => {
+ try {
+ const res = await api.get("/educator/students");
+ setStudents(res.data);
+ } catch (err) {
+ console.error("Failed to fetch students", err);
+ }
+ };
+
+ if (username) fetchHistory();
+ if (role === "educator") fetchStudents();
+ }, [username, role, setQuizHistory, setProfile, progress, addLearnedTopic, removeLearnedTopic]);
+
+ const chartData = quizHistory
+ .map((entry) => ({
+ topic: entry.topic,
+ mastery: (1 - entry.mastery) * 100,
+ date: new Date(entry.createdAt).toLocaleDateString(),
+ fullDate: new Date(entry.createdAt).getTime(),
+ }))
+ .sort((a, b) => a.fullDate - b.fullDate);
+
+ return (
+
+ {!asBackground && (
+ <>
+
+
+
Welcome, {username}!
+
+ {role === "educator"
+ ? "Manage enrolled students and monitor their learning journey."
+ : "This is your personalized learning dashboard."}
+
+
+
+ >
+ )}
+
+ {role === "educator" ? (
+ <>
+
+
+
+
+
π₯ Enrolled Students
+
+
+ {students.length === 0 ? (
+
No students enrolled yet.
+ ) : (
+ students.map((student) => (
+
+
navigate(`/educator/student/${student.username}`)}
+ style={{ cursor: 'pointer', fontSize: '1.25rem' }}
+ >
+
{student.username}
+ {/*
/*Last Active: {new Date(student.lastActive).toLocaleDateString()}
*/ }
+
+
+ ))
+ )}
+
+
+
+ >
+ ) : (
+ <>
+ {/* Student View (same as before) */}
+
+
+
+
Mastery Over Time
+ {chartData.length === 0 ? (
+
No data available yet to show mastery progression.
+ ) : (
+
+ )}
+
+
+
+
+
Current Mastery Levels
+ {Object.keys(mastery).length === 0 ? (
+
No mastery data available. Take some quizzes to get started!
+ ) : (
+
+ {Object.entries(mastery).map(([topic, score]) => (
+
+ {topic}
+ {(1 - score).toFixed(2)} Confidence
+
+ ))}
+
+ )}
+
+
+
+
+
Topics Learned
+
+ {progress.length === 0 ? (
+
No topics marked as completed yet. Keep learning!
+ ) : (
+ progress.map((topic) => (
+
+
+
+ ))
+ )}
+
+
+
+
+
+
Quiz History
+ {quizHistory.length === 0 ? (
+
No quiz attempts recorded yet.
+ ) : (
+
+ {quizHistory.map((entry, i) => (
+
+
+ {entry.topic} β Score: {entry.score}% β Mastery Weight: {entry.mastery}
+
+ {new Date(entry.createdAt).toLocaleString()}
+
+
+ ))}
+
+ )}
+
+ >
+ )}
+
+ );
+};
+
+export default Dashboard;
diff --git a/team-bhavitha-dsarecommender/client/src/pages/DiscussionDetailPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/DiscussionDetailPage.tsx
new file mode 100644
index 000000000..a8b8d0f24
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/DiscussionDetailPage.tsx
@@ -0,0 +1,330 @@
+// src/pages/DiscussionDetailPage.tsx
+import { useEffect, useState } from "react";
+import { useParams } from "react-router-dom";
+import { api } from "../lib/api";
+import LoadingWithQuote from "../components/LoadingWithQuotes";
+import { useUserStore } from "../store/userStore";
+import { Trash2 } from "lucide-react";
+
+interface Reply {
+ _id: string;
+ username: string;
+ role?: string;
+ text: string;
+ createdAt: string;
+}
+
+interface Comment {
+ _id: string;
+ username: string;
+ role?: string;
+ text: string;
+ createdAt: string;
+ replies?: Reply[];
+}
+
+interface DiscussionThread {
+ _id: string;
+ title?: string;
+ question?: string;
+ topic?: string;
+ createdBy?: string;
+ createdAt: string;
+ comments: Comment[];
+}
+
+const DiscussionDetailPage = () => {
+ const username = useUserStore((state) => state.username);
+ const userRole = useUserStore((state) => state.role);
+ const { id } = useParams<{ id: string }>();
+ const [thread, setThread] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [newComment, setNewComment] = useState("");
+ const [submitting, setSubmitting] = useState(false);
+ const [replyTextMap, setReplyTextMap] = useState<{ [commentId: string]: string }>({});
+
+ const fetchThread = async () => {
+ try {
+ setLoading(true);
+ const res = await api.get(`/discuss/thread/${id}`);
+ setThread(res.data);
+ } catch (err) {
+ console.error("Error fetching thread:", err);
+ if (typeof err === "object" && err !== null && "response" in err) {
+ // @ts-ignore
+ alert((err as any).response?.data?.error || "Failed to load thread");
+ } else {
+ alert("Failed to load thread");
+ }
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchThread();
+ }, [id]);
+
+ const handleCommentSubmit = async () => {
+ if (!username) return alert("You must be logged in to comment.");
+ if (!newComment.trim()) return;
+
+ try {
+ setSubmitting(true);
+ await api.post(`/discuss/thread/${id}/comment`, {
+ username,
+ text: newComment,
+ // Optional: Add role if backend doesn't attach it
+ role: userRole
+ });
+ setNewComment("");
+ fetchThread(); // Refresh thread
+ } catch (err) {
+ console.error("Error submitting comment:", err);
+ if (typeof err === "object" && err !== null && "response" in err) {
+ // @ts-ignore
+ alert((err as any).response?.data?.error || "Failed to submit comment");
+ } else {
+ alert("Failed to submit comment");
+ }
+ } finally {
+ setSubmitting(false);
+ }
+ };
+
+ const handleReplySubmit = async (commentId: string) => {
+ const replyText = replyTextMap[commentId];
+ if (!username) return alert("You must be logged in to reply.");
+ if (!replyText?.trim()) return;
+
+ try {
+ await api.post(`/discuss/${id}/comment/${commentId}/reply`, {
+ username,
+ text: replyText,
+ // Optional: Add role if backend doesn't attach it
+ role: userRole
+ });
+ setReplyTextMap((prev) => ({ ...prev, [commentId]: "" }));
+ fetchThread(); // Refresh thread
+ } catch (err) {
+ console.error("Error submitting reply:", err);
+ if (typeof err === "object" && err !== null && "response" in err) {
+ // @ts-ignore
+ alert((err as any).response?.data?.error || "Failed to submit reply");
+ } else {
+ alert("Failed to submit reply");
+ }
+ }
+ };
+
+ const handleDeleteComment = async (commentId: string) => {
+ if (!window.confirm("Are you sure you want to delete this comment?")) return;
+ const { username, role } = useUserStore.getState();
+ try {
+ await api.delete(`/discuss/thread/${id}/comment/${commentId}`,{
+ data: { username, role }
+ });
+ // Optimistic update
+ setThread(prev => prev ? {
+ ...prev,
+ comments: prev.comments.filter(c => c._id !== commentId)
+ } : null);
+ } catch (err) {
+ console.error("Failed to delete comment", err);
+ if (typeof err === "object" && err !== null && "response" in err) {
+ // @ts-ignore
+ alert((err as any).response?.data?.error || "Failed to delete comment");
+ } else {
+ alert("Failed to delete comment");
+ }
+ }
+ };
+
+ const handleDeleteReply = async (commentId: string, replyId: string) => {
+ if (!window.confirm("Are you sure you want to delete this reply?")) return;
+ const { username, role } = useUserStore.getState();
+ try {
+ await api.delete(`/discuss/thread/${id}/comment/${commentId}/reply/${replyId}`,{
+ data: { username, role }
+ });
+ // Optimistic update
+ setThread(prev => {
+ if (!prev) return null;
+ return {
+ ...prev,
+ comments: prev.comments.map(comment => {
+ if (comment._id === commentId) {
+ return {
+ ...comment,
+ replies: comment.replies?.filter(r => r._id !== replyId)
+ };
+ }
+ return comment;
+ })
+ };
+ });
+ } catch (err) {
+ console.error("Failed to delete reply", err);
+ if (typeof err === "object" && err !== null && "response" in err) {
+ // @ts-ignore
+ alert((err as any).response?.data?.error || "Failed to delete reply");
+ } else {
+ alert("Failed to delete reply");
+ }
+ }
+ };
+
+ if (loading) return ;
+ if (!thread) return Thread not found.
;
+
+ return (
+
+
+
+
{thread.title || "Discussion"}
+ {userRole === 'educator' && (
+ Educator Mode
+ )}
+
+
+
{thread.question}
+
+
+
+ Started by {thread.createdBy || "Anonymous"} on{" "}
+ {new Date(thread.createdAt).toLocaleString()}
+
+
+
+
+
+
π¬ Comments
+
+ {thread.comments.length === 0 ? (
+
No comments yet. Be the first to reply!
+ ) : (
+ thread.comments.map((c) => (
+
+
+
+
+ {c.username}
+ {/* Role badge for comment author */}
+ {c.role === 'educator' ? (
+ Educator
+ ) : c.role ? (
+ {c.role}
+ ) : (
+ Student
+ )}
+
+
{c.text}
+
+
+
+
+ {new Date(c.createdAt).toLocaleString()}
+
+ {/* Delete button for educators */}
+ {userRole === 'educator' && (
+ handleDeleteComment(c._id)}
+ >
+
+
+ )}
+
+
+
+ {/* Replies */}
+ {(c.replies?.length ?? 0) > 0 && (
+
+ {c.replies!.map((r) => (
+
+
+
+
+ {r.username}
+ {/* Role badge for reply author */}
+ {r.role === 'educator' ? (
+
+ ) : r.role ? (
+ {r.role}
+ ) : (
+
+ )}
+
+
{r.text}
+
+ {new Date(r.createdAt).toLocaleString()}
+
+
+ {/* Delete button for educators */}
+ {userRole === 'educator' && (
+
handleDeleteReply(c._id, r._id)}
+ >
+
+
+ )}
+
+
+ ))}
+
+ )}
+
+ {/* Reply Input */}
+
+
+ setReplyTextMap((prev) => ({ ...prev, [c._id]: e.target.value }))
+ }
+ />
+
+ handleReplySubmit(c._id)}
+ >
+ Reply
+
+
+
+
+ ))
+ )}
+
+
+ {/* Main Comment Input */}
+
+
π Add a Comment
+
setNewComment(e.target.value)}
+ rows={3}
+ className="form-control mb-3"
+ placeholder="Type your response..."
+ style={{ border: '1px solid #0d6efd', borderRadius: '6px' }}
+ />
+
+
+ {submitting ? "Posting..." : "Post Comment"}
+
+
+
+
+
+ );
+};
+
+export default DiscussionDetailPage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/DiscussionPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/DiscussionPage.tsx
new file mode 100644
index 000000000..3271720e6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/DiscussionPage.tsx
@@ -0,0 +1,393 @@
+import { useEffect, useState } from "react";
+import { api } from "../lib/api";
+import { useUserStore } from "../store/userStore";
+import { useNavigate } from "react-router-dom";
+import { ChevronDown, ChevronUp, Trash2 } from "lucide-react";
+import StartDiscussionModal from "../components/DiscussModal";
+
+interface Comment {
+ _id: string;
+ username: string;
+ text: string;
+ role?: string;
+ createdAt: string;
+ replies: {
+ _id: string;
+ username: string;
+ text: string;
+ role?: string;
+ createdAt: string;
+ }[];
+}
+
+interface Thread {
+ _id: string;
+ isGeneral: boolean;
+ topic?: string;
+ questionIndex?: number;
+ questionText?: string;
+ comments: Comment[];
+ createdAt: string;
+ updatedAt: string;
+}
+
+const Discuss = () => {
+ const username = useUserStore((state) => state.username);
+ const userRole = useUserStore((state) => state.role);
+ const [threads, setThreads] = useState([]);
+ const [expanded, setExpanded] = useState<{ [key: string]: boolean }>({});
+ const [replyBox, setReplyBox] = useState<{ [commentId: string]: string }>({});
+ const [loading, setLoading] = useState(false);
+ const [showModal, setShowModal] = useState(false);
+ const [error, setError] = useState("");
+ const navigate = useNavigate();
+
+ const fetchThreads = async () => {
+ try {
+ setLoading(true);
+ setError("");
+ const res = await api.get("/discuss/all");
+ setThreads(res.data.threads);
+ } catch (err) {
+ console.error("Error fetching threads", err);
+ setError("Failed to load discussions. Please try again later.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+
+const handleDeleteComment = async (threadId: string, commentId: string) => {
+ if (!window.confirm("Are you sure you want to delete this comment?")) return;
+
+ const { username, role } = useUserStore.getState();
+
+ try {
+ await api.delete(`/discuss/thread/${threadId}/comment/${commentId}`, {
+ data: { username, role },
+ });
+
+ setThreads((prev) =>
+ prev.map((thread) => {
+ if (thread._id === threadId) {
+ return {
+ ...thread,
+ comments: thread.comments.filter((c) => c._id !== commentId),
+ };
+ }
+ return thread;
+ })
+ );
+ } catch (err) {
+ console.error("Failed to delete comment", err);
+ const errorMessage =
+ (err as any)?.response?.data?.error || "Only educators or comment owners can delete this comment.";
+ alert(errorMessage);
+ }
+};
+
+
+
+ const handleDeleteReply = async (
+ threadId: string,
+ commentId: string,
+ replyId: string
+ ) => {
+ if (!window.confirm("Are you sure you want to delete this reply?")) return;
+ const { username, role } = useUserStore.getState();
+ try {
+ await api.delete(`/discuss/thread/${threadId}/comment/${commentId}/reply/${replyId}`,{
+ data: { username, role }
+ });
+ // Optimistic update
+ setThreads(prev => prev.map(thread => {
+ if (thread._id === threadId) {
+ return {
+ ...thread,
+ comments: thread.comments.map(comment => {
+ if (comment._id === commentId) {
+ return {
+ ...comment,
+ replies: comment.replies.filter(r => r._id !== replyId)
+ };
+ }
+ return comment;
+ })
+ };
+ }
+ return thread;
+ }));
+ } catch (err) {
+ console.error("Failed to delete reply", err);
+ if (err && typeof err === "object" && "response" in err && err.response && typeof err.response === "object" && "data" in err.response && err.response.data && typeof err.response.data === "object" && "error" in err.response.data) {
+ alert((err as any).response.data.error);
+ } else {
+ alert("Only educators can delete replies");
+ }
+ }
+ };
+
+ const handleReply = async (threadId: string, commentId: string) => {
+ const text = replyBox[commentId];
+ if (!text.trim() || !username) return;
+
+ // Declare tempReplyId outside try-catch so it's accessible in both
+ const tempReplyId = `temp-${Date.now()}`;
+
+ try {
+ // Create optimistic reply
+ setThreads(prev => prev.map(thread => {
+ if (thread._id === threadId) {
+ return {
+ ...thread,
+ comments: thread.comments.map(comment => {
+ if (comment._id === commentId) {
+ return {
+ ...comment,
+ replies: [
+ ...comment.replies,
+ {
+ _id: tempReplyId,
+ username,
+ text,
+ role: userRole,
+ createdAt: new Date().toISOString()
+ }
+ ]
+ };
+ }
+ return comment;
+ })
+ };
+ }
+ return thread;
+ }));
+
+ // Clear reply box immediately
+ setReplyBox(prev => ({ ...prev, [commentId]: "" }));
+
+ // Send actual request
+ await api.post(`/discuss/${threadId}/comment/${commentId}/reply`, {
+ username,
+ text,
+ role: userRole
+ });
+
+ // Refresh data to get actual ID from server
+ fetchThreads();
+ } catch (err) {
+ console.error("Reply failed", err);
+ // Revert optimistic update
+ setThreads(prev => prev.map(thread => {
+ if (thread._id === threadId) {
+ return {
+ ...thread,
+ comments: thread.comments.map(comment => {
+ if (comment._id === commentId) {
+ return {
+ ...comment,
+ replies: comment.replies.filter(r => r._id !== tempReplyId)
+ };
+ }
+ return comment;
+ })
+ };
+ }
+ return thread;
+ }));
+ if (typeof err === "object" && err !== null && "response" in err && (err as any).response?.data?.error) {
+ alert((err as any).response.data.error);
+ } else {
+ alert("Failed to post reply");
+ }
+ }
+ };
+
+ useEffect(() => {
+ fetchThreads();
+ }, []);
+
+ return (
+
+
+ setShowModal(true)}>
+ Start Discussion
+
+
+
+ {loading ? (
+
+
+ Loading...
+
+
Loading discussions...
+
+ ) : error ? (
+
+ {error} Retry
+
+ ) : threads.length === 0 ? (
+
+
No discussions yet
+
Be the first to start a discussion!
+
setShowModal(true)}>
+ Start Discussion
+
+
+ ) : (
+
+ {threads.map((thread) => (
+
+
+
navigate(`/discuss/${thread._id}`)}
+ >
+
{thread.isGeneral ? "π General Discussion" : `π ${thread.topic}`}
+ {thread.comments.length} comments
+
+
+
+ {thread.isGeneral
+ ? thread.comments[0]?.text?.slice(0, 80) + (thread.comments[0]?.text?.length > 80 ? "..." : "")
+ : thread.questionText}
+
+
+ {thread.comments.map((comment) => (
+
+
+
+
+ {comment.username}
+ {comment.role === "educator" ? (
+
+ ) : comment.role ? (
+ {comment.role}
+ ) : (
+
+ )}
+
+
{comment.text}
+
+
+
+ {new Date(comment.createdAt).toLocaleDateString()}
+
+ {userRole === "educator" && (
+ {
+ e.stopPropagation();
+ handleDeleteComment(thread._id, comment._id);
+ }}
+ >
+
+
+ )}
+
+
+
+
{
+ e.stopPropagation();
+ setExpanded((prev) => ({
+ ...prev,
+ [comment._id]: !prev[comment._id],
+ }));
+ }}
+ >
+ {expanded[comment._id] ? (
+ <>
+ Hide Replies
+ >
+ ) : (
+ <>
+ View Replies ({comment.replies.length})
+ >
+ )}
+
+
+ {expanded[comment._id] && (
+
+ {comment.replies.length === 0 ? (
+
No replies yet.
+ ) : (
+ comment.replies.map((reply) => (
+
+
+
+
+ {reply.username}
+ {reply.role === "educator" ? (
+ Educator
+ ) : reply.role ? (
+ {reply.role}
+ ) : (
+ Student
+ )}
+
+
{reply.text}
+
+ {new Date(reply.createdAt).toLocaleDateString()}
+
+
+ {userRole === "educator" && (
+
+ handleDeleteReply(thread._id, comment._id, reply._id)
+ }
+ >
+
+
+ )}
+
+
+ ))
+ )}
+
+
+ setReplyBox((prev) => ({
+ ...prev,
+ [comment._id]: e.target.value,
+ }))
+ }
+ />
+ {
+ e.stopPropagation();
+ handleReply(thread._id, comment._id);
+ }}
+ >
+ Reply
+
+
+ )}
+
+ ))}
+
+
+ ))}
+
+ )}
+
+
setShowModal(false)}
+ onRefresh={fetchThreads}
+ username={username}
+ userRole={userRole}
+ />
+
+ );
+};
+
+export default Discuss;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/ExploreTopicPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/ExploreTopicPage.tsx
new file mode 100644
index 000000000..936cd5ed8
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/ExploreTopicPage.tsx
@@ -0,0 +1,224 @@
+import { useEffect, useState } from "react";
+import { useParams, useNavigate } from "react-router-dom";
+import { api } from "../lib/api";
+import LoadingSpinner from "../components/LoadingSpinner";
+
+interface Concept {
+ name: string;
+ description?: string;
+ spotlight_fact?: string;
+ lecture?: string;
+ examples?: string[];
+ related_topics?: string[];
+ quiz_available?: boolean;
+ structuredNotes?: {
+ overview?: string;
+ keyConcepts?: { name: string; explanation: string }[];
+ frequentlyUsed?: string[];
+ commonPitfalls?: string[];
+ bestPractices?: string[];
+ latestReferences?: string[];
+ };
+}
+
+const ExploreTopicPage = () => {
+ const { topic } = useParams<{ topic: string }>();
+ const [concept, setConcept] = useState(null);
+ const [error, setError] = useState("");
+ const [loading, setLoading] = useState(true);
+ const [isTakingQuiz, setIsTakingQuiz] = useState(false);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (!topic) {
+ setError("No topic specified for exploration.");
+ setLoading(false);
+ return;
+ }
+
+ setLoading(true);
+ api
+ .get(`/explore/${encodeURIComponent(topic)}`)
+ .then((res) => {
+ setConcept(res.data);
+ setError("");
+ })
+ .catch((err) => {
+ console.error("Error fetching concept:", err);
+ setError("Couldn't load concept information. Please try again later.");
+ setConcept(null);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, [topic]);
+
+ const handleTakeQuiz = (selectedTopic: string) => {
+ setIsTakingQuiz(true);
+ setTimeout(() => {
+ navigate(`/quiz/${encodeURIComponent(selectedTopic)}`);
+ setIsTakingQuiz(false);
+ }, 800);
+ };
+
+ if (error) {
+ return (
+
+
+ {error}
+
+
navigate("/dashboard")} className="btn btn-secondary mt-3">
+ Back to Dashboard
+
+
+ );
+ }
+
+ if (loading) {
+ return (
+
+
+ navigate("/dashboard")} className="btn btn-secondary mt-3">
+ Back to Dashboard
+
+
+ );
+ }
+
+ if (!concept) return null;
+
+ const notes = concept.structuredNotes;
+
+ return (
+
+
{concept.name}
+
+ {(concept.description || concept.spotlight_fact || concept.lecture) && (
+
+ {concept.description && (
+
Description: {concept.description}
+ )}
+ {concept.spotlight_fact && (
+
Spotlight Fact: {concept.spotlight_fact}
+ )}
+ {concept.lecture && (
+
Appears in Lecture: {concept.lecture}
+ )}
+
+ )}
+
+ {concept.examples&&concept.examples.length > 0 && (
+
+
Examples:
+
+ {concept.examples.map((ex, i) => (
+ {ex}
+ ))}
+
+
+ )}
+
+ {concept.related_topics&&concept.related_topics?.length > 0 && (
+
+
Related Topics:
+
+ {concept.related_topics.map((related, i) => (
+ {related}
+ ))}
+
+
+ )}
+
+ {notes?.overview && (
+
+
Overview:
+
{notes.overview}
+
+ )}
+
+ {notes&¬es.keyConcepts&¬es.keyConcepts.length > 0 && (
+
+
Key Concepts:
+
+ {notes.keyConcepts.map((kc, i) => (
+
+ {kc.name}: {kc.explanation}
+
+ ))}
+
+
+ )}
+
+ {notes&¬es.frequentlyUsed&¬es.frequentlyUsed?.length > 0 && (
+
+
Frequently Used In Practice:
+
+ {notes.frequentlyUsed.map((item, i) => (
+ {item}
+ ))}
+
+
+ )}
+
+ {notes&¬es.commonPitfalls&¬es.commonPitfalls.length > 0 && (
+
+
Common Pitfalls:
+
+ {notes.commonPitfalls.map((item, i) => (
+ {item}
+ ))}
+
+
+ )}
+
+ {notes&¬es.bestPractices&¬es.bestPractices.length > 0 && (
+
+
Best Practices:
+
+ {notes.bestPractices.map((item, i) => (
+ {item}
+ ))}
+
+
+ )}
+
+ {notes&¬es.latestReferences&¬es.latestReferences.length > 0 && (
+
+
Latest References:
+
+ {notes.latestReferences.map((item, i) => (
+ {item}
+ ))}
+
+
+ )}
+
+
+
+ Quiz Available: {" "}
+
+ {concept.quiz_available ? "Yes!" : "No."}
+
+
+ {concept.quiz_available && (
+
handleTakeQuiz(concept.name)}
+ className="btn btn-primary btn-lg mt-3 mt-md-0"
+ disabled={isTakingQuiz}
+ >
+ {isTakingQuiz ? : "Take Quiz Now"}{" "}
+
+
+ )}
+
+
+
+ navigate("/dashboard")} className="btn btn-secondary btn-lg">
+ Back to Dashboard
+
+
+
+ );
+};
+
+export default ExploreTopicPage;
diff --git a/team-bhavitha-dsarecommender/client/src/pages/HomePage.tsx b/team-bhavitha-dsarecommender/client/src/pages/HomePage.tsx
new file mode 100644
index 000000000..719b393dd
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/HomePage.tsx
@@ -0,0 +1,332 @@
+import { useNavigate } from 'react-router-dom';
+import { useAuthStore } from '../store/authStore';
+import { motion } from 'framer-motion';
+import { BookOpen, Target, TrendingUp, Users, ArrowRight, Award, Lightbulb } from 'lucide-react';
+
+const HomePage = () => {
+ const navigate = useNavigate();
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
+
+ const handleQuizNavigation = () => {
+ navigate(isAuthenticated ? '/quiz-select' : '/login');
+ };
+
+ const handleExploreNavigation = () => {
+ navigate('/explore');
+ };
+
+ const handleRecommendationNavigation = () => {
+ navigate(isAuthenticated ? '/dashboard' : '/login');
+ };
+
+ const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.2,
+ delayChildren: 0.1
+ }
+ }
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, y: 30 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ const cardVariants = {
+ hidden: { opacity: 0, scale: 0.9 },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ },
+ hover: {
+ scale: 1.05,
+ y: -8,
+ transition: {
+ duration: 0.3,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+
+ {/* Hero Section */}
+
+
+
+
+ Welcome to LearnFlow!
+
+
+
+
+
+
+
+
+
+ {/* Get Started Section */}
+
+
+
navigate('/register')}
+ >
+
+
+
+
+
New to LearnFlow?
+
+
+ Get Started Free
+
+
+
+
+
+
+
navigate('/login')}
+ >
+
+
+
+
+
Already a Member?
+
+
+ Sign In
+
+
+
+
+
+
+
+ {/* Features Section */}
+
+
+
+
+ Unlock Your Potential with LearnFlow
+
+
+
+
+ {[
+ {
+ icon: Target,
+ title: "Personalized Paths",
+ description: "Discover the shortest learning path from your current knowledge to your target concept.",
+ color: "text-primary"
+ },
+ {
+ icon: TrendingUp,
+ title: "Adaptive Quizzes",
+ description: "Test your understanding and adapt your progress path based on quiz performance.",
+ color: "text-success"
+ },
+ {
+ icon: BookOpen,
+ title: "Progress Tracking",
+ description: "Visualize your journey through quizzes, weights, and time recommendations.",
+ color: "text-warning"
+ },
+ {
+ icon: Lightbulb,
+ title: "Knowledge Graph",
+ description: "Build deep conceptual understanding through connected topic paths.",
+ color: "text-info"
+ }
+ ].map((feature, index) => (
+
+
+
+
+
+
+
{feature.title}
+
+
+
+
+ ))}
+
+
+
+
+ {/* Action Buttons */}
+
+
+
+
+ Ready to Start?
+
+
+
+
+
+
+ Take a Quiz
+
+
+
+ Explore Topics
+
+
+
+ Get Recommendation
+
+
+
+
+
+ {/* Stats Section */}
+
+
+
+
+
+
+
+ 1000+
+
+
+
+
+
+ 50+
+
+
+
+
+
+ 95%
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default HomePage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/LoginPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/LoginPage.tsx
new file mode 100644
index 000000000..9fa6a6aa7
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/LoginPage.tsx
@@ -0,0 +1,211 @@
+import { useState } from "react";
+import { useNavigate, Link } from "react-router-dom";
+import { authApi } from "../lib/api";
+import { useAuthStore } from "../store/authStore";
+import { useUserStore } from "../store/userStore";
+import LoadingWithQuote from "../components/LoadingWithQuotes";
+import { motion } from "framer-motion";
+import { LogIn, User, Lock, Eye, EyeOff, AlertCircle } from "lucide-react";
+
+const LoginPage = () => {
+ const [username, setUsername] = useState("");
+ const [password, setPassword] = useState("");
+ const [error, setError] = useState("");
+ const [isLoading, setIsLoading] = useState(false);
+ const [showPassword, setShowPassword] = useState(false);
+
+ const login = useAuthStore((state) => state.login);
+ const setProfile = useUserStore((state) => state.setProfile);
+ const navigate = useNavigate();
+
+ const handleLogin = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setError("");
+ setIsLoading(true);
+
+ try {
+ const res = await authApi.post("/login", { username, password });
+ if (res.status === 200) {
+ const userData = res.data.user;
+ login(userData.username, userData.role);
+ setProfile(userData);
+ navigate(`/dashboard/${userData.username}`);
+ }
+ } catch (err: unknown) {
+ const errorMessage = err instanceof Error ? err.message : "Login failed. Please check your credentials.";
+ setError(errorMessage);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const containerVariants = {
+ hidden: { opacity: 0, y: 50 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6,
+ ease: "easeOut" as const,
+ staggerChildren: 0.1
+ }
+ }
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, x: -20 },
+ visible: {
+ opacity: 1,
+ x: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ Welcome Back
+
+
+ {isLoading ? (
+
+ ) : (
+
+
+
+
+ Username
+
+
+ setUsername(e.target.value)}
+ placeholder="Enter your username"
+ required
+ disabled={isLoading}
+ />
+
+
+
+
+
+
+ Password
+
+
+ setPassword(e.target.value)}
+ placeholder="Enter your password"
+ required
+ disabled={isLoading}
+ />
+ setShowPassword(!showPassword)}
+ whileHover={{ scale: 1.1 }}
+ whileTap={{ scale: 0.9 }}
+ style={{ zIndex: 10 }}
+ >
+ {showPassword ? : }
+
+
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+
+ Sign In
+
+ )}
+
+
+ )}
+
+ {error && (
+
+
+ {error}
+
+ )}
+
+
+
+ Don't have an account?{" "}
+
+
+ Register
+
+
+
+
+
+
+
+ );
+};
+
+export default LoginPage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/PlaygroundPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/PlaygroundPage.tsx
new file mode 100644
index 000000000..82b88a4d2
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/PlaygroundPage.tsx
@@ -0,0 +1,207 @@
+import React, { useEffect, useState } from "react";
+import { api } from "../lib/api";
+import { useAuthStore } from "../store/authStore";
+import AttemptHistory from "../components/AttemptHistory";
+import { validTopics } from "../data/validTopic";
+
+type Question = { concept: string; question: string };
+type Result = {
+ strongConcepts: string[];
+ weakConcepts: string[];
+ recommendedConcepts: string[];
+};
+
+const PlaygroundPage = () => {
+ const { username: user } = useAuthStore();
+ const [inputConcept, setInputConcept] = useState("");
+ const [concept, setConcept] = useState("");
+ const [sessionId, setSessionId] = useState("");
+ const [question, setQuestion] = useState(null);
+ const [result, setResult] = useState(null);
+ const [history, setHistory] = useState>({});
+ const [loading, setLoading] = useState(false);
+
+ useEffect(() => {
+ const loadHistory = async () => {
+ const localData = localStorage.getItem("playgroundHistory");
+ if (localData) {
+ setHistory(JSON.parse(localData));
+ return;
+ }
+
+ if (!user) return;
+
+ try {
+ const res = await api.get(`/user/${user}/playground-attempts`);
+ setHistory(res.data);
+ localStorage.setItem("playgroundHistory", JSON.stringify(res.data));
+ } catch (err) {
+ console.error("Error loading previous attempts", err);
+ }
+ };
+ loadHistory();
+ }, [user]);
+
+ const handleStart = async () => {
+ if (!inputConcept || !user) return;
+
+ if (history[inputConcept]) {
+ setConcept(inputConcept);
+ setResult(history[inputConcept]);
+ setQuestion(null);
+ return;
+ }
+
+ try {
+ setLoading(true);
+ const res = await api.get("/start", {
+ params: { concept: inputConcept, userId: user },
+ });
+
+ setConcept(inputConcept);
+ setSessionId(res.data.sessionId);
+ setQuestion(res.data.question);
+ setResult(null);
+ } catch (err) {
+ console.error("Failed to start session", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const handleAnswer = async (answer: "yes" | "no") => {
+ try {
+ const res = await api.post("/answer", {
+ sessionId,
+ answer,
+ });
+
+ if (res.data.isComplete) {
+ setResult(res.data.results);
+ setHistory((prev) => {
+ const updated = { ...prev, [concept]: res.data.results };
+ localStorage.setItem("playgroundHistory", JSON.stringify(updated));
+ return updated;
+ });
+ setQuestion(null);
+ } else {
+ setQuestion(res.data.question);
+ }
+ } catch (err) {
+ console.error("Answer submission failed", err);
+ }
+ };
+
+ return (
+
+
+
+
+
+
Dhruv Playground
+
Your Path to Mastery
+
+
+
+
+ {/* Left: Playground (Main) */}
+
+
+
+
{ e.preventDefault(); handleStart(); }}>
+
+ setInputConcept(e.target.value)}
+ className="form-select form-select-lg bg-black text-white border-primary"
+ disabled={loading}
+ >
+ Select a topic...
+ {validTopics.map((topic, idx) => (
+
+ {topic}
+
+ ))}
+
+
+
+
+ {history[inputConcept] ? "View Attempt" : "Start"}
+
+
+
+ {loading &&
β³ Generating questions...
}
+
+ {question && (
+
+
+ Concept: {question.concept}
+
+
{question.question}
+
+ handleAnswer("yes")}
+ className="btn btn-success px-4 py-2 fs-5"
+ >
+ Yes
+
+ handleAnswer("no")}
+ className="btn btn-danger px-4 py-2 fs-5"
+ >
+ No
+
+
+
+ )}
+
+ {result && (
+
+
β
Session Summary
+
+
+
+ Strong Concepts:
+ {result.strongConcepts.join(", ") || "None"}
+
+
+
+
+ Weak Concepts:
+ {result.weakConcepts.join(", ") || "None"}
+
+
+
+
+ Recommended:
+ {result.recommendedConcepts.join(", ") || "None"}
+
+
+
+
+ )}
+
+
+
+
+ {/* Right: Knowledge Trail - only show when not answering questions */}
+ {!question && (
+
+
+
+
π Knowledge Trail
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default PlaygroundPage;
diff --git a/team-bhavitha-dsarecommender/client/src/pages/QuizPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/QuizPage.tsx
new file mode 100644
index 000000000..9cae836b6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/QuizPage.tsx
@@ -0,0 +1,344 @@
+// src/pages/QuizPage.tsx
+import { useEffect, useState } from "react";
+import { useParams, useNavigate } from "react-router-dom";
+import { api } from "../lib/api";
+import { useUserStore } from "../store/userStore";
+import LoadingWithQuote from "../components/LoadingWithQuotes";
+import { useQuizStore } from "../store/quizStore"; // β
Import Zustand store
+
+interface MCQQuestion {
+ question: string;
+ options: string[];
+}
+
+interface QuizSummary {
+ topic: string;
+ score: number;
+ masteryUpdate: Record;
+ correctAnswers?: string[];
+ userAnswers?: string[];
+}
+
+const QuizPage = () => {
+ const { topic } = useParams<{ topic: string }>();
+ const navigate = useNavigate();
+ const username = useUserStore((state) => state.username);
+ const updateProfile = useUserStore((state) => state.setProfile);
+ const currentMastery = useUserStore((state) => state.mastery);
+ const addLearnedTopic = useUserStore((state) => state.addLearnedTopic);
+ const quizHistory = useUserStore((state) => state.quizHistory);
+ const setQuizHistory = useUserStore((state) => state.setQuizHistory);
+ const progress = useUserStore((state) => state.progress);
+
+ const [loading, setLoading] = useState(true);
+ const [isSubmitting, setIsSubmitting] = useState(false);
+ const [error, setError] = useState(null);
+ const [questions, setQuestions] = useState([]);
+ const [answers, setAnswers] = useState([]);
+ const [submitted, setSubmitted] = useState(false);
+ const [summary, setSummary] = useState(null);
+ const [correctAnswers, setCorrectAnswers] = useState([]);
+ const [showSolution, setShowSolution] = useState([]);
+
+ const quizStore = useQuizStore();
+
+ useEffect(() => {
+ const fetchQuiz = async () => {
+ if (!topic) {
+ setError("No topic specified");
+ setLoading(false);
+ return;
+ }
+
+ // β
Use cached quiz if same topic
+ if (quizStore.topic === topic) {
+ setQuestions(quizStore.questions);
+ setCorrectAnswers(quizStore.correctAnswers);
+ setAnswers(new Array(quizStore.questions.length).fill(""));
+ setShowSolution(new Array(quizStore.questions.length).fill(false));
+ setLoading(false);
+ return;
+ }
+
+ // β
Otherwise, fetch new quiz
+ try {
+ setLoading(true);
+ const res = await api.get(`/quiz/${encodeURIComponent(topic)}`);
+ const fetchedQuestions = res.data.questions;
+
+ if (!Array.isArray(fetchedQuestions)) {
+ throw new Error("Invalid questions format received from server");
+ }
+
+ setQuestions(fetchedQuestions);
+ setCorrectAnswers(res.data._correctAnswers || []);
+ setAnswers(new Array(fetchedQuestions.length).fill(""));
+ setShowSolution(new Array(fetchedQuestions.length).fill(false));
+
+ // β
Cache quiz in Zustand
+ quizStore.setQuizData({
+ topic,
+ questions: fetchedQuestions,
+ correctAnswers: res.data._correctAnswers || [],
+ });
+ } catch (err) {
+ const errorMessage =
+ err instanceof Error ? err.message : "Failed to load quiz questions";
+ console.error("Quiz loading error:", err);
+ setError(errorMessage);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchQuiz();
+ }, [topic, quizStore]);
+
+ const handleOptionSelect = (qIndex: number, selected: string) => {
+ if (submitted) return;
+ setAnswers((prev) => {
+ const newAnswers = [...prev];
+ newAnswers[qIndex] = selected;
+ return newAnswers;
+ });
+ };
+
+ const toggleSolution = (index: number) => {
+ setShowSolution((prev) => {
+ const updated = [...prev];
+ updated[index] = !updated[index];
+ return updated;
+ });
+ };
+
+ const handleDiscuss = async (index: number) => {
+ const questionText = questions[index].question;
+ try {
+ const res = await api.post("/discuss/create-or-get", {
+ topic,
+ questionText,
+ questionIndex: index,
+ username,
+ });
+ const threadId = res.data._id;
+ navigate(`/discuss/${threadId}`);
+ } catch (err) {
+ console.error("Failed to open discussion thread:", err);
+ alert("Unable to open discussion thread. Please try again.");
+ }
+ };
+
+ const handleAsk = (index: number) => {
+ const questionText = questions[index].question;
+ alert(`Opening educator Q&A for Q${index + 1}: "${questionText}"`);
+ };
+
+ const handleReport = (index: number) => {
+ const questionText = questions[index].question;
+ alert(`Reporting issue for Q${index + 1}: "${questionText}"`);
+ };
+
+ const handleSubmit = async () => {
+ if (!topic) return;
+ if (questions.length === 0 || answers.some((a) => a === "")) {
+ alert("Please answer all questions before submitting.");
+ return;
+ }
+
+ try {
+ setIsSubmitting(true);
+ setSubmitted(true);
+
+ const res = await api.post("/quiz/submit", {
+ topic,
+ answers,
+ username,
+ _correctAnswers: correctAnswers,
+ });
+
+ const masteryValue = res.data.masteryUpdate?.[topic];
+ setSummary(res.data);
+
+ updateProfile({
+ mastery: {
+ ...currentMastery,
+ ...res.data.masteryUpdate,
+ },
+ });
+
+ if (
+ typeof masteryValue === "number" &&
+ (1 - masteryValue) >= 0.7 &&
+ !progress.includes(topic)
+ ) {
+ addLearnedTopic(topic);
+ }
+
+ const newEntry = {
+ topic,
+ score: res.data.score,
+ mastery: masteryValue,
+ createdAt: new Date().toISOString(),
+ };
+ setQuizHistory([...quizHistory, newEntry]);
+ } catch (err) {
+ const errorMessage =
+ err instanceof Error ? err.message : "Failed to submit quiz";
+ console.error("Quiz submission error:", err);
+ setError(errorMessage);
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ if (loading) {
+ return (
+
+
+
Loading quiz questions...
+
+ );
+ }
+
+ if (error) {
+ return (
+
+
Error
+
{error}
+
navigate("/dashboard")}
+ className="btn btn-primary btn-lg px-5"
+ >
+ Return to Dashboard
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ {questions.length === 0 ? (
+
+ No questions available for this topic.
+
+ ) : (
+
e.preventDefault()}>
+ {questions.map((q, i) => (
+
+
+ {i + 1}. {q.question}
+
+
+ {q.options.map((option, optionIndex) => (
+
+ handleOptionSelect(i, option)}
+ disabled={submitted || isSubmitting}
+ className="form-check-input me-3"
+ style={{ transform: "scale(1.4)" }}
+ />
+ {option}
+
+ ))}
+
+
+
+ handleDiscuss(i)}
+ >
+ π£οΈ Discuss
+
+ handleAsk(i)}
+ >
+ β Ask
+
+ handleReport(i)}
+ >
+ π Report
+
+ toggleSolution(i)}
+ >
+ π {showSolution[i] ? "Hide" : "View"} Solution
+
+
+
+ {showSolution[i] && submitted && summary?.correctAnswers?.[i] && (
+
+ Solution: {summary.correctAnswers[i]} β *(Add explanation text here)*
+
+ )}
+
+ ))}
+
+ {!submitted && (
+ a === "") || answers.length === 0 || isSubmitting}
+ className="btn btn-primary btn-lg w-100 mt-4"
+ >
+ {isSubmitting ? : "Submit Quiz"}
+
+ )}
+
+ )}
+
+ {summary && (
+
+
Quiz Results
+
+ Score: {summary.score.toFixed(1)}%
+
+ {summary.masteryUpdate && topic && (
+
+ Mastery Level: {" "}
+ {((1 - (summary.masteryUpdate[topic] || 0)) * 100).toFixed(1)}%
+
+ )}
+
navigate("/dashboard")}
+ className="btn btn-primary btn-lg px-5"
+ >
+ Return to Dashboard
+
+
+ )}
+
+
+
+ );
+};
+
+export default QuizPage;
diff --git a/team-bhavitha-dsarecommender/client/src/pages/QuizSelectPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/QuizSelectPage.tsx
new file mode 100644
index 000000000..cb859d218
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/QuizSelectPage.tsx
@@ -0,0 +1,59 @@
+// client/src/pages/QuizSelectPage.tsx
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { validTopics } from "../data/validTopic";
+import LoadingSpinner from "../components/LoadingSpinner"; // Import LoadingSpinner
+
+const QuizSelectPage = () => {
+ const [selectedTopic, setSelectedTopic] = useState("");
+ const [isLoading, setIsLoading] = useState(false); // State for button loading
+ const navigate = useNavigate();
+
+ const handleSubmit = () => {
+ if (selectedTopic.trim()) {
+ setIsLoading(true); // Start loading animation
+ // Simulate a network delay or processing time before navigation
+ setTimeout(() => {
+ navigate(`/quiz/${encodeURIComponent(selectedTopic.trim())}`);
+ setIsLoading(false); // End loading (though navigation changes page)
+ }, 800); // 800ms delay for demonstration
+ }
+ };
+
+ return (
+
+
+
+
+
+
Select a Topic for Quiz
+
+ setSelectedTopic(e.target.value)}
+ className="form-select form-select-lg border-primary"
+ style={{ maxWidth: '350px' }}
+ disabled={isLoading}
+ >
+ Select a topic...
+ {validTopics.map((topic: string, i: number) => (
+ {topic}
+ ))}
+
+
+
+ {isLoading ? : "Take Quiz"}
+
+
+
+
+
+
+ );
+};
+
+export default QuizSelectPage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/RecommendationPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/RecommendationPage.tsx
new file mode 100644
index 000000000..2261ea233
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/RecommendationPage.tsx
@@ -0,0 +1,148 @@
+// src/pages/RecommendationPage.tsx
+
+import { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useUserStore } from "../store/userStore";
+import { validTopics } from "../data/validTopic";
+import {api} from "../lib/api";
+
+const RecommendationPage = () => {
+ const username = useUserStore((state) => state.username);
+ const navigate = useNavigate();
+
+ const [startConcept, setStartConcept] = useState("");
+ const [endConcept, setEndConcept] = useState("");
+ const [recommendedPath, setRecommendedPath] = useState([]);
+ const [error, setError] = useState(null);
+
+ const handleGetPath = async () => {
+ setError(null);
+ if (!startConcept.trim() || !endConcept.trim()) {
+ setError("Please select both start and target concepts.");
+ setRecommendedPath([]);
+ return;
+ }
+
+ try {
+ const res = await api.post("/recommendation", {
+ start: startConcept.trim(),
+ end: endConcept.trim(),
+ username,
+ });
+
+ setRecommendedPath(res.data.path || []);
+ if (res.data.path?.length === 0) {
+ setError("No path found between the selected concepts.");
+ }
+ } catch (err: any) {
+ console.error("Error fetching recommendation:", err);
+ setError(err.response?.data?.error || "Something went wrong.");
+ }
+ };
+
+ const handleTakeQuiz = (topic: string) => {
+ navigate(`/quiz/${encodeURIComponent(topic)}`);
+ };
+
+ const handleExplore = (topic: string) => {
+ navigate(`/explore/${encodeURIComponent(topic)}`);
+ };
+
+ return (
+
+
+
+
+
Get Learning Path Recommendation
+
+
+
+
+
+
+
+
+
+
+ setStartConcept(e.target.value)}
+ className="form-select form-select-lg border-primary"
+ >
+ Select Start Concept
+ {validTopics.filter((t) => t !== endConcept).map((topic) => (
+
+ {topic}
+
+ ))}
+
+
+
+ setEndConcept(e.target.value)}
+ className="form-select form-select-lg border-primary"
+ >
+ Select Target Concept
+ {validTopics.filter((t) => t !== startConcept).map((topic) => (
+
+ {topic}
+
+ ))}
+
+
+
+
+ Get Path
+
+
+
+
+
+ {error &&
{error}
}
+
+
+
+ {recommendedPath.length > 0 && (
+
+ )}
+
+ );
+};
+
+export default RecommendationPage;
diff --git a/team-bhavitha-dsarecommender/client/src/pages/RegisterPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/RegisterPage.tsx
new file mode 100644
index 000000000..6e0cc2b5c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/RegisterPage.tsx
@@ -0,0 +1,404 @@
+import { useState } from "react";
+import { useNavigate, Link } from "react-router-dom";
+import { authApi } from "../lib/api";
+import { useAuthStore } from "../store/authStore";
+import { useUserStore } from "../store/userStore";
+import Select from "react-select";
+import { validTopics } from "../data/validTopic";
+import { Eye, EyeOff, User, Mail, Lock, BookOpen, GraduationCap } from "lucide-react";
+import LoadingWithQuotes from "../components/LoadingWithQuotes";
+import { motion } from "framer-motion";
+
+const RegisterPage = () => {
+ const [name, setName] = useState("");
+ const [username, setUsername] = useState("");
+ const [role, setRole] = useState<"student" | "educator">("student");
+ const [eid, setEid] = useState("");
+ const [password, setPassword] = useState("");
+ const [confirmPassword, setConfirmPassword] = useState("");
+ const [email, setEmail] = useState("");
+ const [topics, setTopics] = useState([]);
+ const [selectedTopics, setSelectedTopics] = useState<{ value: string; label: string }[]>([]);
+ const [error, setError] = useState("");
+ const [isLoading, setIsLoading] = useState(false);
+ const [showPassword, setShowPassword] = useState(false);
+ const [showConfirmPassword, setShowConfirmPassword] = useState(false);
+
+ const login = useAuthStore((state) => state.login);
+ const setProfile = useUserStore((state) => state.setProfile);
+ const navigate = useNavigate();
+
+ const getPasswordStrength = (password: string): { score: number; label: string } => {
+ let score = 0;
+ if (password.length >= 6) score++;
+ if (/[A-Z]/.test(password)) score++;
+ if (/[!@#$%^&*(),.?":{}|<>]/.test(password)) score++;
+ if (password.length >= 10) score++;
+
+ const labels = ["Too Weak", "Weak", "Moderate", "Strong", "Very Strong"];
+ return { score, label: labels[score] };
+ };
+
+ const passwordStrength = getPasswordStrength(password);
+
+ const handleRegister = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setError("");
+ setIsLoading(true);
+
+ if (password !== confirmPassword) {
+ setError("Passwords do not match.");
+ setIsLoading(false);
+ return;
+ }
+
+ if (!/[A-Z]/.test(password) || !/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
+ setError("Password must contain at least one uppercase letter and one special character.");
+ setIsLoading(false);
+ return;
+ }
+ if (role === "educator") {
+ const eidPattern = /^\d{16}$/;
+ if (!eidPattern.test(eid.trim())) {
+ setError("Educator ID must be exactly 16 digits.");
+ setIsLoading(false);
+ return;
+ }
+ }
+
+ try {
+ const userPayload = {
+ name,
+ username,
+ password,
+ email,
+ progress: topics,
+ role,
+ eid: role === "educator" ? eid.trim() : undefined,
+ };
+
+ const res = await authApi.post("/register", userPayload);
+
+ if (res.status === 201) {
+ const userData = res.data.user;
+ login(userData.username, userData.role);
+ setProfile(userData);
+ navigate(`/dashboard/${userData.username}`);
+ }
+ } catch (err: unknown) {
+ const errorMessage = err instanceof Error ? err.message : "Registration failed. Please try again.";
+ setError(errorMessage);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ const containerVariants = {
+ hidden: { opacity: 0, y: 50 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6,
+ ease: "easeOut" as const,
+ staggerChildren: 0.1
+ }
+ }
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, x: -20 },
+ visible: {
+ opacity: 1,
+ x: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ Create Account
+
+
+ {isLoading ? (
+
+ ) : (
+
+
+
+
+
+
+
+ Email
+
+
+ setEmail(e.target.value)}
+ required
+ disabled={isLoading}
+ />
+
+
+
+
+
+
+ Role
+
+
+ setRole(e.target.value as "student" | "educator")}
+ disabled={isLoading}
+ >
+ Student
+ Educator
+
+
+
+
+
+ {role === "educator" && (
+
+
+
+ Educator ID
+
+
+ setEid(e.target.value)}
+ required={role === "educator"}
+ disabled={isLoading}
+ />
+
+
+ )}
+
+
+
+
+
+ Password
+
+
+ setPassword(e.target.value)}
+ required
+ disabled={isLoading}
+ />
+ setShowPassword(!showPassword)}
+ whileHover={{ scale: 1.1 }}
+ whileTap={{ scale: 0.9 }}
+ style={{ zIndex: 10 }}
+ >
+ {showPassword ? : }
+
+
+
+
+
+
Strength: {passwordStrength.label}
+
+
+
+
+
+ Confirm Password
+
+
+ setConfirmPassword(e.target.value)}
+ required
+ disabled={isLoading}
+ />
+ setShowConfirmPassword(!showConfirmPassword)}
+ whileHover={{ scale: 1.1 }}
+ whileTap={{ scale: 0.9 }}
+ style={{ zIndex: 10 }}
+ >
+ {showConfirmPassword ? : }
+
+
+
+
+
+
+ {isLoading ? (
+
+
+ Creating Account...
+
+ ) : (
+
+
+ Create Account
+
+ )}
+
+
+ )}
+
+ {error && (
+
+ {error}
+
+ )}
+
+
+
+ Already have an account?{" "}
+
+
+ Sign In
+
+
+
+
+
+
+
+ );
+};
+
+export default RegisterPage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/pages/StudentAssignments.tsx b/team-bhavitha-dsarecommender/client/src/pages/StudentAssignments.tsx
new file mode 100644
index 000000000..359ef6196
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/StudentAssignments.tsx
@@ -0,0 +1,526 @@
+import { useEffect, useState } from "react";
+import { api } from "../lib/api";
+import { useUserStore } from "../store/userStore";
+import { motion, AnimatePresence } from "framer-motion";
+import {
+ FileText,
+ Calendar,
+ Download,
+ Eye,
+ Clock,
+ CheckCircle,
+ AlertCircle,
+ Search,
+ BookOpen,
+ Award
+} from "lucide-react";
+import LoadingSpinner from "../components/LoadingSpinner";
+
+interface Assignment {
+ _id: string;
+ title: string;
+ description: string;
+ fileUrl: string;
+ createdAt: string;
+ status?: 'pending' | 'completed' | 'overdue';
+ dueDate?: string;
+ subject?: string;
+ difficulty?: 'easy' | 'medium' | 'hard';
+}
+
+export default function StudentAssignments() {
+ const username = useUserStore((state) => state.username);
+ const [assignments, setAssignments] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [searchTerm, setSearchTerm] = useState("");
+ const [filterStatus, setFilterStatus] = useState("all");
+ const [sortBy, setSortBy] = useState("date");
+ const [selectedAssignment, setSelectedAssignment] = useState(null);
+ const [showModal, setShowModal] = useState(false);
+
+ useEffect(() => {
+ const loadAssignments = async () => {
+ try {
+ const cached = localStorage.getItem("studentAssignments");
+ if (cached) setAssignments(JSON.parse(cached));
+
+ const res = await api.get(`/assignments/${username}`);
+ // Add mock data for demonstration
+ const enhancedAssignments = res.data.map((assignment: Assignment) => ({
+ ...assignment,
+ status: Math.random() > 0.5 ? 'pending' : 'completed',
+ dueDate: new Date(Date.now() + Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString(),
+ subject: ['Computer Science', 'Mathematics', 'Physics', 'Chemistry'][Math.floor(Math.random() * 4)],
+ difficulty: ['easy', 'medium', 'hard'][Math.floor(Math.random() * 3)] as 'easy' | 'medium' | 'hard'
+ }));
+ setAssignments(enhancedAssignments);
+ localStorage.setItem("studentAssignments", JSON.stringify(enhancedAssignments));
+ } catch (err) {
+ console.error("Failed to load assignments", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ loadAssignments();
+ }, [username]);
+
+ if (!username) {
+ return (
+
+
+
+ Please log in to view your assignments.
+
+
+ );
+ }
+
+ const filteredAssignments = assignments
+ .filter(assignment => {
+ const matchesSearch = assignment.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ assignment.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ assignment.subject?.toLowerCase().includes(searchTerm.toLowerCase());
+ const matchesFilter = filterStatus === "all" || assignment.status === filterStatus;
+ return matchesSearch && matchesFilter;
+ })
+ .sort((a, b) => {
+ switch (sortBy) {
+ case "date":
+ return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
+ case "dueDate":
+ return new Date(a.dueDate || 0).getTime() - new Date(b.dueDate || 0).getTime();
+ case "title":
+ return a.title.localeCompare(b.title);
+ case "subject":
+ return (a.subject || "").localeCompare(b.subject || "");
+ default:
+ return 0;
+ }
+ });
+
+ const getStatusBadge = (status: string) => {
+ switch (status) {
+ case 'completed':
+ return Completed ;
+ case 'pending':
+ return Pending ;
+ case 'overdue':
+ return Overdue ;
+ default:
+ return Unknown ;
+ }
+ };
+
+ const getDifficultyBadge = (difficulty: string) => {
+ switch (difficulty) {
+ case 'easy':
+ return Easy ;
+ case 'medium':
+ return Medium ;
+ case 'hard':
+ return Hard ;
+ default:
+ return Unknown ;
+ }
+ };
+
+ const isOverdue = (dueDate: string) => {
+ return new Date(dueDate) < new Date();
+ };
+
+ const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2
+ }
+ }
+ };
+
+ const itemVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ const cardVariants = {
+ hidden: { opacity: 0, scale: 0.9 },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ transition: {
+ duration: 0.4,
+ ease: "easeOut" as const
+ }
+ },
+ hover: {
+ scale: 1.02,
+ y: -5,
+ transition: {
+ duration: 0.2,
+ ease: "easeOut" as const
+ }
+ }
+ };
+
+ if (loading) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+ {/* Header Section */}
+
+
+
+
My Assignments
+
+ Track and manage your learning assignments
+
+ {/* Stats Cards */}
+
+
+
+ {assignments.length}
+ Total Assignments
+
+
+
+
+
+ {assignments.filter(a => a.status === 'completed').length}
+
+ Completed
+
+
+
+
+
+ {assignments.filter(a => a.status === 'pending').length}
+
+ Pending
+
+
+
+
+
+ {assignments.filter(a => a.status === 'overdue').length}
+
+ Overdue
+
+
+
+
+
+ {/* Filters and Search */}
+
+
+
+
+
+
+
+
+
+ setSearchTerm(e.target.value)}
+ />
+
+
+
+ setFilterStatus(e.target.value)}
+ >
+ All Status
+ Pending
+ Completed
+ Overdue
+
+
+
+ setSortBy(e.target.value)}
+ >
+ Sort by Date
+ Sort by Due Date
+ Sort by Title
+ Sort by Subject
+
+
+
+
+
+
+
+ {/* Assignments Grid */}
+
+
+ {filteredAssignments.length === 0 ? (
+
+
+ No assignments found
+
+ {searchTerm || filterStatus !== "all"
+ ? "Try adjusting your search or filter criteria."
+ : "You don't have any assignments yet. Check back later!"}
+
+
+ ) : (
+
+
+ {filteredAssignments.map((assignment) => (
+
+ {
+ setSelectedAssignment(assignment);
+ setShowModal(true);
+ }}
+ style={{ cursor: 'pointer' }}
+ >
+
+
+
+ {assignment.title}
+
+ {getStatusBadge(assignment.status || 'pending')}
+
+
+
+ {assignment.description}
+
+
+
+
+
+
+
+ Assigned: {new Date(assignment.createdAt).toLocaleDateString()}
+
+
+ {assignment.dueDate && (
+
+
+
+ Due: {new Date(assignment.dueDate).toLocaleDateString()}
+
+
+ )}
+
+
+
+
+ {assignment.subject && (
+ {assignment.subject}
+ )}
+ {assignment.difficulty && getDifficultyBadge(assignment.difficulty)}
+
+
+ {
+ e.stopPropagation();
+ window.open(assignment.fileUrl, '_blank');
+ }}
+ >
+
+ View
+
+ {
+ e.stopPropagation();
+ const link = document.createElement('a');
+ link.href = assignment.fileUrl;
+ link.download = assignment.title;
+ link.click();
+ }}
+ >
+
+ Download
+
+
+
+
+
+
+
+ ))}
+
+
+ )}
+
+
+
+ {/* Assignment Detail Modal */}
+ {showModal && selectedAssignment && (
+
+
+
+
+
+
+ {selectedAssignment.title}
+
+ setShowModal(false)}
+ >
+
+
+
+
+
Description
+
{selectedAssignment.description}
+
+
+
Details
+
+
+ Status:
+ {getStatusBadge(selectedAssignment.status || 'pending')}
+
+
+ Subject:
+ {selectedAssignment.subject || 'N/A'}
+
+
+ Difficulty:
+ {selectedAssignment.difficulty && getDifficultyBadge(selectedAssignment.difficulty)}
+
+
+ Assigned:
+ {new Date(selectedAssignment.createdAt).toLocaleDateString()}
+
+ {selectedAssignment.dueDate && (
+
+ Due Date:
+
+ {new Date(selectedAssignment.dueDate).toLocaleDateString()}
+
+
+ )}
+
+
+
+
+ window.open(selectedAssignment.fileUrl, '_blank')}
+ >
+
+ View Assignment
+
+ {
+ const link = document.createElement('a');
+ link.href = selectedAssignment.fileUrl;
+ link.download = selectedAssignment.title;
+ link.click();
+ }}
+ >
+
+ Download
+
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/team-bhavitha-dsarecommender/client/src/pages/StudentDetailPage.tsx b/team-bhavitha-dsarecommender/client/src/pages/StudentDetailPage.tsx
new file mode 100644
index 000000000..d388f07c8
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/pages/StudentDetailPage.tsx
@@ -0,0 +1,185 @@
+// client/src/pages/StudentDetailPage.tsx
+import { useEffect, useState } from "react";
+import { useParams, useNavigate } from "react-router-dom";
+import { api } from "../lib/api";
+import LearnedConceptCard from "../components/LearnedConceptCard";
+import AssignTaskModal from "../components/AssignTaskModal";
+import {
+ LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer,
+} from "recharts";
+
+interface QuizEntry {
+ topic: string;
+ score: number;
+ mastery: number;
+ createdAt: string;
+}
+
+const StudentDetailPage = () => {
+ const { username } = useParams<{ username: string }>();
+ const navigate = useNavigate();
+ const [quizHistory, setQuizHistory] = useState([]);
+ const [progress, setProgress] = useState([]);
+ const [error, setError] = useState("");
+ const [showModal, setShowModal] = useState(false);
+
+ useEffect(() => {
+ if (!username) return;
+
+ const fetchStudentData = async () => {
+ try {
+ const res = await api.get(`/quiz-history/${username}`);
+ if (Array.isArray(res.data)) {
+ setQuizHistory(res.data);
+
+ const masteryMap: Record = {};
+ res.data.forEach((entry) => {
+ if (!masteryMap[entry.topic]) masteryMap[entry.topic] = [];
+ masteryMap[entry.topic].push(entry.mastery);
+ });
+
+ const updatedMastery: Record = {};
+ const learned: string[] = [];
+
+ Object.entries(masteryMap).forEach(([topic, scores]) => {
+ const avg = scores.reduce((a, b) => a + b, 0) / scores.length;
+ updatedMastery[topic] = avg;
+ const confidence = (1 - avg) * 100;
+ if (confidence >= 70) learned.push(topic);
+ });
+
+ // setMastery(updatedMastery); // This line is removed as per the edit hint
+ setProgress(learned);
+ }
+ } catch (err) {
+ setError("Failed to fetch student data");
+ console.error(err);
+ }
+ };
+
+ fetchStudentData();
+ }, [username]);
+
+ const chartData = quizHistory
+ .map((entry) => ({
+ topic: entry.topic,
+ mastery: (1 - entry.mastery) * 100,
+ date: new Date(entry.createdAt).toLocaleDateString(),
+ fullDate: new Date(entry.createdAt).getTime(),
+ }))
+ .sort((a, b) => a.fullDate - b.fullDate);
+
+
+
+ return (
+
+
+
+
+
π Student: {username}
+ {error &&
{error}
}
+
+
+
+
+ {/* Mastery Over Time */}
+
+
+
+
+
π Mastery Over Time
+ {chartData.length === 0 ? (
+
No data to display.
+ ) : (
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+ {/* Learned Topics */}
+
+
+
+
+
β
Learned Topics
+ {progress.length === 0 ? (
+
No topics learned yet.
+ ) : (
+
+ {progress.map((topic) => (
+
+
+ q.topic === topic)
+ .map(q => ({ score: q.score, date: q.createdAt }))
+ } />
+
+
+ ))}
+
+ )}
+
+
+
+
+
+ {/* Quiz History */}
+
+
+
+
+
π§ͺ Quiz History
+ {quizHistory.length === 0 ? (
+
No quizzes attempted yet.
+ ) : (
+
+ {quizHistory.map((entry, i) => (
+
+ {entry.topic} β Score: {entry.score}%, Mastery: {entry.mastery}
+
+ {new Date(entry.createdAt).toLocaleString()}
+
+ ))}
+
+ )}
+
+
+
+
+ {/* Assign Task Button */}
+
setShowModal(true)}
+ >
+ Assign Task
+
+
+
setShowModal(false)}
+ username={username || ""}
+ />
+
+
+
+ navigate(-1)}>Back to Dashboard
+
+
+
+ );
+};
+
+export default StudentDetailPage;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/client/src/routes/AppEntry.tsx b/team-bhavitha-dsarecommender/client/src/routes/AppEntry.tsx
new file mode 100644
index 000000000..7a2de40f4
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/routes/AppEntry.tsx
@@ -0,0 +1,21 @@
+// src/routes/AppEntry.tsx
+import { useEffect } from "react";
+import { useNavigate } from "react-router-dom";
+import { useAuthStore } from "../store/authStore";
+
+const AppEntry = () => {
+ const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (isAuthenticated) {
+ navigate("/dashboard");
+ } else {
+ navigate("/home");
+ }
+ }, [isAuthenticated]);
+
+ return null; // no UI
+};
+
+export default AppEntry;
diff --git a/team-bhavitha-dsarecommender/client/src/store/authStore.ts b/team-bhavitha-dsarecommender/client/src/store/authStore.ts
new file mode 100644
index 000000000..9e0ea063f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/store/authStore.ts
@@ -0,0 +1,25 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+interface AuthState {
+ isAuthenticated: boolean;
+ username: string;
+ role: "student" | "educator" | ""; // "" = default when not logged in
+ login: (username: string, role: "student" | "educator") => void;
+ logout: () => void;
+}
+
+export const useAuthStore = create()(
+ persist(
+ (set) => ({
+ isAuthenticated: false,
+ username: "",
+ role: "",
+ login: (username, role) => set({ isAuthenticated: true, username, role }),
+ logout: () => set({ isAuthenticated: false, username: "", role: "" }),
+ }),
+ {
+ name: "auth-storage", // Key in localStorage
+ }
+ )
+);
diff --git a/team-bhavitha-dsarecommender/client/src/store/quizStore.ts b/team-bhavitha-dsarecommender/client/src/store/quizStore.ts
new file mode 100644
index 000000000..fe225e0a5
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/store/quizStore.ts
@@ -0,0 +1,27 @@
+import { create } from "zustand";
+
+interface MCQQuestion {
+ question: string;
+ options: string[];
+}
+
+interface QuizState {
+ topic: string | null;
+ questions: MCQQuestion[];
+ correctAnswers: string[];
+ setQuizData: (data: {
+ topic: string;
+ questions: MCQQuestion[];
+ correctAnswers: string[];
+ }) => void;
+ clearQuizData: () => void;
+}
+
+export const useQuizStore = create((set) => ({
+ topic: null,
+ questions: [],
+ correctAnswers: [],
+ setQuizData: ({ topic, questions, correctAnswers }) =>
+ set({ topic, questions, correctAnswers }),
+ clearQuizData: () => set({ topic: null, questions: [], correctAnswers: [] }),
+}));
diff --git a/team-bhavitha-dsarecommender/client/src/store/userStore.ts b/team-bhavitha-dsarecommender/client/src/store/userStore.ts
new file mode 100644
index 000000000..65f75770c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/src/store/userStore.ts
@@ -0,0 +1,63 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+interface UserProfile {
+ username: string;
+ email?: string;
+ mastery: Record;
+ progress: string[];
+ recommendations: string[];
+ quizHistory: any[];
+ role?: "student" | "educator";
+ setQuizHistory: (history: any[]) => void;
+ setProfile: (profile: Partial) => void;
+ clearProfile: () => void;
+ addLearnedTopic: (topic: string) => void;
+ removeLearnedTopic: (topic: string) => void;
+}
+
+export const useUserStore = create()(
+ persist(
+ (set) => ({
+ username: "",
+ email: "",
+ mastery: {},
+ progress: [],
+ recommendations: [],
+ quizHistory: [],
+ setQuizHistory: (history) => set({ quizHistory: history }),
+ setProfile: (profile) =>
+ set((state) => ({
+ ...state,
+ mastery: {
+ ...state.mastery,
+ ...profile.mastery, // β
merge mastery
+ },
+ ...profile,
+ })),
+ clearProfile: () =>
+ set({
+ username: "",
+ email: "",
+ mastery: {},
+ progress: [],
+ recommendations: [],
+ quizHistory: [],
+ }),
+ addLearnedTopic: (topic) =>
+ set((state) =>
+ state.progress.includes(topic)
+ ? state
+ : { progress: [...state.progress, topic] }
+ ),
+ removeLearnedTopic: (topic: string) =>
+ set((state) => ({
+ progress: state.progress.filter((t) => t !== topic),
+ }))
+
+ }),
+ {
+ name: "user-profile",
+ }
+ )
+);
diff --git a/project-alpha/frontend/src/vite-env.d.ts b/team-bhavitha-dsarecommender/client/src/vite-env.d.ts
similarity index 100%
rename from project-alpha/frontend/src/vite-env.d.ts
rename to team-bhavitha-dsarecommender/client/src/vite-env.d.ts
diff --git a/project-alpha/frontend/tsconfig.app.json b/team-bhavitha-dsarecommender/client/tsconfig.app.json
similarity index 91%
rename from project-alpha/frontend/tsconfig.app.json
rename to team-bhavitha-dsarecommender/client/tsconfig.app.json
index c9ccbd4c5..604c6fabc 100644
--- a/project-alpha/frontend/tsconfig.app.json
+++ b/team-bhavitha-dsarecommender/client/tsconfig.app.json
@@ -17,8 +17,8 @@
/* Linting */
"strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
diff --git a/project-alpha/frontend/tsconfig.json b/team-bhavitha-dsarecommender/client/tsconfig.json
similarity index 100%
rename from project-alpha/frontend/tsconfig.json
rename to team-bhavitha-dsarecommender/client/tsconfig.json
diff --git a/project-alpha/frontend/tsconfig.node.json b/team-bhavitha-dsarecommender/client/tsconfig.node.json
similarity index 90%
rename from project-alpha/frontend/tsconfig.node.json
rename to team-bhavitha-dsarecommender/client/tsconfig.node.json
index 9728af2d8..3373ac4a4 100644
--- a/project-alpha/frontend/tsconfig.node.json
+++ b/team-bhavitha-dsarecommender/client/tsconfig.node.json
@@ -15,8 +15,8 @@
/* Linting */
"strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
diff --git a/team-bhavitha-dsarecommender/client/vercel.json b/team-bhavitha-dsarecommender/client/vercel.json
new file mode 100644
index 000000000..6a9264870
--- /dev/null
+++ b/team-bhavitha-dsarecommender/client/vercel.json
@@ -0,0 +1,5 @@
+{
+ "rewrites": [
+ { "source": "/(.*)", "destination": "/" }
+ ]
+}
diff --git a/project-alpha/frontend/vite.config.ts b/team-bhavitha-dsarecommender/client/vite.config.ts
similarity index 50%
rename from project-alpha/frontend/vite.config.ts
rename to team-bhavitha-dsarecommender/client/vite.config.ts
index 8b0f57b91..04e9bde7e 100644
--- a/project-alpha/frontend/vite.config.ts
+++ b/team-bhavitha-dsarecommender/client/vite.config.ts
@@ -1,7 +1,14 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
-// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
+ server: {
+ proxy: {
+ '/api': {
+ target: 'http://localhost:5000',
+ changeOrigin: true,
+ },
+ },
+ },
})
diff --git a/team-bhavitha-dsarecommender/concept-graph.py b/team-bhavitha-dsarecommender/concept-graph.py
deleted file mode 100644
index 30ca7d102..000000000
--- a/team-bhavitha-dsarecommender/concept-graph.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import networkx as nx
-import matplotlib.pyplot as plt
-import json
-from networkx.readwrite import json_graph
-concept_map = {
- "What is computation?": ["Computation", "Algorithms", "Problem Solving"],
- "Branching and Iteration": ["Conditionals", "Loops", "Control Flow"],
- "String Manipulation, Guess and Check, Approximations, Bisection": [
- "String Manipulation", "Guess and Check", "Approximation", "Bisection Search"
- ],
- "Decomposition, Abstractions, Functions": ["Decomposition", "Abstraction", "Functions"],
- "Tuples, Lists, Aliasing, Mutability, Cloning": [
- "Tuples", "Lists", "Aliasing", "Mutability", "Cloning"
- ],
- "Recursion, Dictionaries": ["Recursion", "Dictionaries"],
- "Testing, Debugging, Exceptions, Assertions": [
- "Testing", "Debugging", "Exceptions", "Assertions"
- ],
- "Object Oriented Programming": ["Classes", "OOP", "Encapsulation"],
- "Python Classes and Inheritance": ["Inheritance", "Subclasses", "Class Hierarchies"],
- "Understanding Program Efficiency, Part 1": ["Big-O Notation", "Efficiency"],
- "Understanding Program Efficiency, Part 2": ["Efficiency", "Space Complexity"],
- "Searching and Sorting": ["Search Algorithms", "Sorting Algorithms"],
-}
-
-G = nx.DiGraph()
-
-# Converted concept_map to a list of concept lists in lecture order
-concept_lists = list(concept_map.values())
-
-# graph
-for i, concepts in enumerate(concept_lists):
- # Connected all concepts within the same lecture in sequence
- for j in range(len(concepts) - 1):
- G.add_edge(concepts[j], concepts[j + 1])
-
- # Connected last concept of this lecture to all concepts in the next lecture
- if i < len(concept_lists) - 1:
- last_concept = concepts[-1]
- next_concepts = concept_lists[i + 1]
- for next_concept in next_concepts:
- G.add_edge(last_concept, next_concept)
-
-
-data = json_graph.node_link_data(G)
-
-# Saved to json file
-with open("concept_graph_full.json", "w", encoding="utf-8") as f:
- json.dump(data, f, indent=4)
-
-print("Full graph saved to concept_graph_full.json")
-
-
-'''
-plt.figure(figsize=(22, 14))
-pos = nx.spring_layout(G, k=0.5, seed=42)
-nx.draw(G, pos, with_labels=True,
- node_color="lightblue", node_size=2500,
- edge_color="gray", arrows=True, width=2, font_size=10)
-plt.title("Concept Graph from Manually Curated Lecture Concepts", fontsize=14)
-plt.axis("off")
-plt.tight_layout()
-plt.show()
-'''
diff --git a/team-bhavitha-dsarecommender/concept_graph.html b/team-bhavitha-dsarecommender/concept_graph.html
deleted file mode 100644
index 2cca5e29b..000000000
--- a/team-bhavitha-dsarecommender/concept_graph.html
+++ /dev/null
@@ -1,127 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/concept_graph.json b/team-bhavitha-dsarecommender/concept_graph.json
deleted file mode 100644
index 3d27267d3..000000000
--- a/team-bhavitha-dsarecommender/concept_graph.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- { "id": "1", "name": "What is computation?", "prerequisites": [] },
- { "id": "2", "name": "Branching and Iteration", "prerequisites": ["1"] },
- { "id": "3", "name": "String Manipulation, Guess and Check, Approximations, Bisection", "prerequisites": ["2"] },
- { "id": "4", "name": "Decomposition, Abstractions, Functions", "prerequisites": ["3"] },
- { "id": "5", "name": "Tuples, Lists, Aliasing, Mutability, Cloning", "prerequisites": ["4"] },
- { "id": "6", "name": "Recursion, Dictionaries", "prerequisites": ["5"] },
- { "id": "7", "name": "Testing, Debugging, Exceptions, Assertions", "prerequisites": ["6"] },
- { "id": "8", "name": "Object Oriented Programming", "prerequisites": ["7"] },
- { "id": "9", "name": "Python Classes and Inheritance", "prerequisites": ["8"] },
- { "id": "10", "name": "Understanding Program Efficiency, Part 1", "prerequisites": ["9"] },
- { "id": "11", "name": "Understanding Program Efficiency, Part 2", "prerequisites": ["10"] },
- { "id": "12", "name": "Searching and Sorting", "prerequisites": ["11"] }
-]
diff --git a/team-bhavitha-dsarecommender/concept_graph_full.json b/team-bhavitha-dsarecommender/concept_graph_full.json
deleted file mode 100644
index cba0230ab..000000000
--- a/team-bhavitha-dsarecommender/concept_graph_full.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "nodes": [
- {
- "id": "Variables",
- "resources": [
- {
- "title": "OCW Lecture: Variables",
- "url": "https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/resources/lecture-1/"
- }
- ]
- },
- {
- "id": "Loops",
- "resources": [
- {
- "title": "OCW Lecture: Loops",
- "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-3/"
- }
- ]
- },
- {
- "id": "Computation",
- "resources": [
- {
- "title": "OCW Lecture: Computational Thinking",
- "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-5/"
- }
- ]
- }
- ],
- "links": [
- { "source": "Variables", "target": "Loops" },
- { "source": "Loops", "target": "Computation" }
- ]
-}
diff --git a/team-bhavitha-dsarecommender/fetch_lectures.py b/team-bhavitha-dsarecommender/fetch_lectures.py
deleted file mode 100644
index cd6fc9092..000000000
--- a/team-bhavitha-dsarecommender/fetch_lectures.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import requests
-import time
-from bs4 import BeautifulSoup
-from bs4.element import Tag
-import json
-
-url = "https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/pages/lecture-slides-code/"
-
-session = requests.Session()
-time.sleep(2) # Sleep to avoid overwhelming the server
-r = session.get(url)
-
-with open("lecture_slides_code.html", "w", encoding='utf-8') as f:
- f.write(r.text)
-print("HTML content retrieved and saved to lecture_slides_code.html")
-
-with open("lecture_slides_code.html", "r", encoding='utf-8') as f:
- html_content = f.read()
-
-soup = BeautifulSoup(html_content, 'html.parser')
-rows = soup.find_all("tr")
-
-lecture_titles = []
-
-for row in rows:
- if isinstance(row, Tag):
- cols = row.find_all("td")
- if len(cols) >= 2:
- title = cols[1].get_text(strip=True)
- if title:
- lecture_titles.append(title)
-
-# Save lecture titles to a text file (optional)
-with open("lecture_titles.txt", "w", encoding='utf-8') as f:
- for title in lecture_titles:
- f.write(title + "\n")
-
-print(f"Extracted {len(lecture_titles)} lecture titles and saved to lecture_titles.txt")
-
-# Save lecture titles to JSON file
-with open("lecture_titles.json", "w", encoding='utf-8') as f_json:
- json.dump(lecture_titles, f_json, ensure_ascii=False, indent=2)
-
-print(f"Saved {len(lecture_titles)} lecture titles to lecture_titles.json")
diff --git a/team-bhavitha-dsarecommender/learner_profiles.json b/team-bhavitha-dsarecommender/learner_profiles.json
deleted file mode 100644
index cb9629820..000000000
--- a/team-bhavitha-dsarecommender/learner_profiles.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "learner_id": "L001",
- "mastered_concepts": ["Computation", "Algorithms"],
- "weak_concepts": ["Problem Solving"]
- },
- {
- "learner_id": "L002",
- "mastered_concepts": ["Computation"],
- "weak_concepts": []
- }
-]
diff --git a/team-bhavitha-dsarecommender/lecture_prerequisites_graph (1).png b/team-bhavitha-dsarecommender/lecture_prerequisites_graph (1).png
deleted file mode 100644
index b134c4ff9..000000000
Binary files a/team-bhavitha-dsarecommender/lecture_prerequisites_graph (1).png and /dev/null differ
diff --git a/team-bhavitha-dsarecommender/lecture_slides_code.html b/team-bhavitha-dsarecommender/lecture_slides_code.html
deleted file mode 100644
index d20ba7daf..000000000
--- a/team-bhavitha-dsarecommender/lecture_slides_code.html
+++ /dev/null
@@ -1,2695 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Lecture Slides and Code | Introduction to Computer Science and Programming in Python | Electrical Engineering and Computer Science | MIT OpenCourseWare
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6.0001 | Fall 2016 | Undergraduate
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Menu
-
-
-
-
-
-
-
-
-
- More Info
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Syllabus
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Readings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The slides and code from each lecture are available below.
-
-
-
-
-
-
-
-
-SESΓΒ #
-
-
-
-
-TOPICS
-
-
-
-
-LECTURE SLIDES
-
-
-
-
-LECTURE CODES
-
-
-
-
-
-
-
-
-
-
-1
-
-
-
-
-What is computation?
-
-
-
-
-Slides for Lecture 1 (PDF)
-
-
-
-
-Code for Lecture 1 (PY)
-
-
-
-
-
-
-
-
-2
-
-
-
-
-Branching and Iteration
-
-
-
-
-Slides for Lecture 2 (PDF)
-
-
-
-
-Code for Lecture 2 (PY)
-
-
-
-
-
-
-
-
-3
-
-
-
-
-String Manipulation, Guess and Check, Approximations, Bisection
-
-
-
-
-Slides for Lecture 3 (PDF)
-
-
-
-
-Code for Lecture 3 (PY)
-
-
-
-
-
-
-
-
-4
-
-
-
-
-Decomposition, Abstractions, Functions
-
-
-
-
-Slides for Lecture 4 (PDF 1.1MB)
-
-
-
-
-Code for Lecture 4 (PY)
-
-
-
-
-
-
-
-
-5
-
-
-
-
-Tuples, Lists, Aliasing, Mutability, Cloning
-
-
-
-
-Slides for Lecture 5 (PDF)
-
-
-
-
-Code for Lecture 5 (PY)
-
-
-
-
-
-
-
-
-6
-
-
-
-
-Recursion, Dictionaries
-
-
-
-
-Slides for Lecture 6 (PDF - 1.3MB)
-
-
-
-
-Code for Lecture 6 (PY)
-
-
-
-
-
-
-
-
-7
-
-
-
-
-Testing, Debugging, Exceptions, Assertions
-
-
-
-
-Slides for Lecture 7 (PDF)
-
-
-
-
-Code for Lecture 7 (PY)
-
-
-
-
-
-
-
-
-8
-
-
-
-
-Object Oriented Programming
-
-
-
-
-Slides for Lecture 8 (PDF)
-
-
-
-
-Code for Lecture 8 (PY)
-
-
-
-
-
-
-
-
-9
-
-
-
-
-Python Classes and Inheritance
-
-
-
-
-Slides for Lecture 9 (PDF - 1.6MB)
-
-
-
-
-Code for Lecture 9 (PY)
-
-
-
-
-
-
-
-
-10
-
-
-
-
-Understanding Program Efficiency, Part 1
-
-
-
-
-Slides for Lecture 10 (PDF)
-
-
-
-
-Code for Lecture 10 (PY)
-
-
-
-
-
-
-
-
-11
-
-
-
-
-Understanding Program Efficiency, Part 2
-
-
-
-
-Slides for Lecture 11 (PDF)
-
-
-
-
-Code for Lecture 11 (PY)
-
-
-
-
-
-
-
-
-12
-
-
-
-
-Searching and Sorting
-
-
-
-
-Slides for Lecture 12 (PDF - 2.4MB)
-
-
-
-
-Code for Lecture 12 (PY)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Course Info
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- As Taught In
-
-
- Fall
-
- 2016
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Topics
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Learning Resource Types
-
-
-
-
-
-
-
-
-
- assignment
- Problem Sets
-
-
-
-
-
-
-
-
-
-
- notes
- Lecture Notes
-
-
-
-
-
-
-
-
-
-
- theaters
- Lecture Videos
-
-
-
-
-
-
-
-
-
-
- assignment_turned_in
- Programming Assignments with Examples
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please be advised that external sites may have terms and conditions,
- including license rights, that differ from ours. MIT OCW is not responsible
- for any content on third party sites, nor does a link suggest an endorsement
- of those sites and/or their content.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/team-bhavitha-dsarecommender/lecture_titles.json b/team-bhavitha-dsarecommender/lecture_titles.json
deleted file mode 100644
index 8c72a7882..000000000
--- a/team-bhavitha-dsarecommender/lecture_titles.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- "What is computation?",
- "Branching and Iteration",
- "String Manipulation, Guess and Check, Approximations, Bisection",
- "Decomposition, Abstractions, Functions",
- "Tuples, Lists, Aliasing, Mutability, Cloning",
- "Recursion, Dictionaries",
- "Testing, Debugging, Exceptions, Assertions",
- "Object Oriented Programming",
- "Python Classes and Inheritance",
- "Understanding Program Efficiency, Part 1",
- "Understanding Program Efficiency, Part 2",
- "Searching and Sorting"
-]
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/lecture_titles.txt b/team-bhavitha-dsarecommender/lecture_titles.txt
deleted file mode 100644
index 8925ad0df..000000000
--- a/team-bhavitha-dsarecommender/lecture_titles.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-What is computation?
-Branching and Iteration
-String Manipulation, Guess and Check, Approximations, Bisection
-Decomposition, Abstractions, Functions
-Tuples, Lists, Aliasing, Mutability, Cloning
-Recursion, Dictionaries
-Testing, Debugging, Exceptions, Assertions
-Object Oriented Programming
-Python Classes and Inheritance
-Understanding Program Efficiency, Part 1
-Understanding Program Efficiency, Part 2
-Searching and Sorting
diff --git a/team-bhavitha-dsarecommender/lectures.json b/team-bhavitha-dsarecommender/lectures.json
deleted file mode 100644
index 96e794672..000000000
--- a/team-bhavitha-dsarecommender/lectures.json
+++ /dev/null
@@ -1,8 +0,0 @@
-[
- { "id": 1, "title": "Introduction to Python" },
- { "id": 2, "title": "Data Types and Variables" },
- { "id": 3, "title": "Control Structures" },
- { "id": 4, "title": "Functions" },
- { "id": 5, "title": "Modules and Packages" },
- { "id": 6, "title": "Object-Oriented Programming" }
-]
diff --git a/team-bhavitha-dsarecommender/package-lock.json b/team-bhavitha-dsarecommender/package-lock.json
index 54a2be663..79f57fe8b 100644
--- a/team-bhavitha-dsarecommender/package-lock.json
+++ b/team-bhavitha-dsarecommender/package-lock.json
@@ -1,1224 +1,6 @@
{
- "name": "learning_path",
- "version": "1.0.0",
+ "name": "team-bhavitha-dsarecommender",
"lockfileVersion": 3,
"requires": true,
- "packages": {
- "": {
- "name": "learning_path",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "bcryptjs": "^3.0.2",
- "cors": "^2.8.5",
- "express": "^5.1.0",
- "jsonwebtoken": "^9.0.2",
- "mongodb": "^6.17.0",
- "mongoose": "^8.15.1"
- }
- },
- "node_modules/@mongodb-js/saslprep": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.2.2.tgz",
- "integrity": "sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==",
- "license": "MIT",
- "dependencies": {
- "sparse-bitfield": "^3.0.3"
- }
- },
- "node_modules/@types/webidl-conversions": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
- "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
- "license": "MIT"
- },
- "node_modules/@types/whatwg-url": {
- "version": "11.0.5",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
- "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
- "license": "MIT",
- "dependencies": {
- "@types/webidl-conversions": "*"
- }
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/bcryptjs": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
- "integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
- "license": "BSD-3-Clause",
- "bin": {
- "bcrypt": "bin/bcrypt"
- }
- },
- "node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/bson": {
- "version": "6.10.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
- "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.20.1"
- }
- },
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/debug": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
- "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/http-errors/node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
- },
- "node_modules/jsonwebtoken": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
- "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
- "license": "MIT",
- "dependencies": {
- "jws": "^3.2.2",
- "lodash.includes": "^4.3.0",
- "lodash.isboolean": "^3.0.3",
- "lodash.isinteger": "^4.0.4",
- "lodash.isnumber": "^3.0.3",
- "lodash.isplainobject": "^4.0.6",
- "lodash.isstring": "^4.0.1",
- "lodash.once": "^4.0.0",
- "ms": "^2.1.1",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- }
- },
- "node_modules/jwa": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
- "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
- "license": "MIT",
- "dependencies": {
- "buffer-equal-constant-time": "^1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
- "license": "MIT",
- "dependencies": {
- "jwa": "^1.4.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/kareem": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
- "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/lodash.includes": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
- "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
- "license": "MIT"
- },
- "node_modules/lodash.isboolean": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
- "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
- "license": "MIT"
- },
- "node_modules/lodash.isinteger": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
- "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
- "license": "MIT"
- },
- "node_modules/lodash.isnumber": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
- "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
- "license": "MIT"
- },
- "node_modules/lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
- "license": "MIT"
- },
- "node_modules/lodash.isstring": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
- "license": "MIT"
- },
- "node_modules/lodash.once": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
- "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
- "license": "MIT"
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "license": "MIT"
- },
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mongodb": {
- "version": "6.17.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.17.0.tgz",
- "integrity": "sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.4",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
- }
- },
- "node_modules/mongodb-connection-string-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
- "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/whatwg-url": "^11.0.2",
- "whatwg-url": "^14.1.0 || ^13.0.0"
- }
- },
- "node_modules/mongoose": {
- "version": "8.15.1",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.15.1.tgz",
- "integrity": "sha512-RhQ4DzmBi5BNGcS0w4u1vdMRIKcteXTCNzDt1j7XRcdWYBz1MjMjulBhPaeC5jBCHOD1yinuOFTTSOWLLGexWw==",
- "license": "MIT",
- "dependencies": {
- "bson": "^6.10.3",
- "kareem": "2.6.3",
- "mongodb": "~6.16.0",
- "mpath": "0.9.0",
- "mquery": "5.0.0",
- "ms": "2.1.3",
- "sift": "17.1.3"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mongoose"
- }
- },
- "node_modules/mongoose/node_modules/mongodb": {
- "version": "6.16.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.16.0.tgz",
- "integrity": "sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@mongodb-js/saslprep": "^1.1.9",
- "bson": "^6.10.3",
- "mongodb-connection-string-url": "^3.0.0"
- },
- "engines": {
- "node": ">=16.20.1"
- },
- "peerDependencies": {
- "@aws-sdk/credential-providers": "^3.188.0",
- "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
- "gcp-metadata": "^5.2.0",
- "kerberos": "^2.0.1",
- "mongodb-client-encryption": ">=6.0.0 <7",
- "snappy": "^7.2.2",
- "socks": "^2.7.1"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-providers": {
- "optional": true
- },
- "@mongodb-js/zstd": {
- "optional": true
- },
- "gcp-metadata": {
- "optional": true
- },
- "kerberos": {
- "optional": true
- },
- "mongodb-client-encryption": {
- "optional": true
- },
- "snappy": {
- "optional": true
- },
- "socks": {
- "optional": true
- }
- }
- },
- "node_modules/mpath": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
- "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/mquery": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
- "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
- "license": "MIT",
- "dependencies": {
- "debug": "4.x"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-to-regexp": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
- "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
- "license": "MIT",
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
- "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/sift": {
- "version": "17.1.3",
- "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
- "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
- "license": "MIT"
- },
- "node_modules/sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
- "license": "MIT",
- "dependencies": {
- "memory-pager": "^1.0.2"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tr46": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
- "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/type-is": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
- "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
- "license": "MIT",
- "dependencies": {
- "content-type": "^1.0.5",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-url": {
- "version": "14.2.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
- "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "^5.1.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- }
- }
+ "packages": {}
}
diff --git a/team-bhavitha-dsarecommender/package.json b/team-bhavitha-dsarecommender/package.json
deleted file mode 100644
index 55c87c70d..000000000
--- a/team-bhavitha-dsarecommender/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "learning_path",
- "version": "1.0.0",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC",
- "description": "",
- "dependencies": {
- "bcryptjs": "^3.0.2",
- "cors": "^2.8.5",
- "express": "^5.1.0",
- "jsonwebtoken": "^9.0.2",
- "mongodb": "^6.17.0",
- "mongoose": "^8.15.1"
- }
-}
diff --git a/team-bhavitha-dsarecommender/recommendation_engine.py b/team-bhavitha-dsarecommender/recommendation_engine.py
deleted file mode 100644
index 571a8f03e..000000000
--- a/team-bhavitha-dsarecommender/recommendation_engine.py
+++ /dev/null
@@ -1,71 +0,0 @@
-import json
-import networkx as nx
-import os
-
-# === Paths ===
-GRAPH_FILE = 'concept_graph_full.json'
-
-LEARNER_FILE = 'learner_profiles.json'
-
-OUTPUT_DIR = 'graph/recommendations/'
-
-# === Load concept graph as DiGraph ===
-with open(GRAPH_FILE) as f:
- graph_data = json.load(f)
-G = nx.node_link_graph(graph_data, directed=True, multigraph=False)
-
-# === Load learner profiles ===
-with open(LEARNER_FILE) as f:
- learners = json.load(f)
-
-# === Ensure output directory exists ===
-os.makedirs(OUTPUT_DIR, exist_ok=True)
-
-def recommend_for_learner(profile):
- mastered = set(profile['mastered_concepts'])
- recommendations = []
-
- for node in G.nodes:
- if node in mastered:
- continue
- prereqs = list(G.predecessors(node))
- if all(p in mastered for p in prereqs):
- recommendations.append(node)
-
- return recommendations
-def recommend_path(learner_profile, goal_concept):
- mastered = set(learner_profile['mastered_concepts'])
-
- # Find shortest path from any mastered node to goal_concept
- shortest_path = None
- min_length = float('inf')
-
- for concept in mastered:
- if nx.has_path(G, concept, goal_concept):
- try:
- path = nx.dijkstra_path(G, source=concept, target=goal_concept)
- if len(path) < min_length:
- shortest_path = path
- min_length = len(path)
- except nx.NetworkXNoPath:
- continue
-
- return shortest_path if shortest_path else []
-
-
-# === Optional batch processing ===
-if __name__ == '__main__':
- for learner in learners:
- learner_id = learner['learner_id']
- recommended = recommend_for_learner(learner)
-
- output = {
- 'learner_id': learner_id,
- 'recommended_concepts': recommended
- }
-
- output_path = os.path.join(OUTPUT_DIR, f'recommendations_{learner_id}.json')
- with open(output_path, 'w') as f:
- json.dump(output, f, indent=4)
-
- print(f"[β] Recommendations saved for {learner_id}: {recommended}")
diff --git a/team-bhavitha-dsarecommender/recommendations.json b/team-bhavitha-dsarecommender/recommendations.json
deleted file mode 100644
index a52ec9236..000000000
--- a/team-bhavitha-dsarecommender/recommendations.json
+++ /dev/null
@@ -1,10 +0,0 @@
-[
- {
- "learner_id": "L001",
- "recommended_path": ["Problem Solving", "Conditionals", "Loops", "Control Flow"]
- },
- {
- "learner_id": "L002",
- "recommended_path": ["Algorithms", "Problem Solving", "Conditionals"]
- }
-]
diff --git a/team-bhavitha-dsarecommender/server.js b/team-bhavitha-dsarecommender/server.js
deleted file mode 100644
index 62f86991a..000000000
--- a/team-bhavitha-dsarecommender/server.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const express = require('express');
-const fs = require('fs');
-const cors = require('cors');
-const app = express();
-const PORT = 5000;
-
-app.use(cors());
-
-app.get('/api/lectures', (req, res) => {
- const data = fs.readFileSync('lectures.json', 'utf-8');
- res.json(JSON.parse(data));
-});
-
-app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));
diff --git a/team-bhavitha-dsarecommender/server.py b/team-bhavitha-dsarecommender/server.py
deleted file mode 100644
index d7b59be55..000000000
--- a/team-bhavitha-dsarecommender/server.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from flask import Flask, request, jsonify
-from recommendation_engine import recommend_for_learner
-
-app = Flask(__name__)
-
-@app.route('/recommend', methods=['POST'])
-def recommend():
- data = request.get_json()
- response = recommend_for_learner(data)
- return jsonify(response)
-
-if __name__ == '__main__':
- app.run(debug=True)
diff --git a/team-bhavitha-dsarecommender/server/.gitignore b/team-bhavitha-dsarecommender/server/.gitignore
new file mode 100644
index 000000000..c610ae3af
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/.gitignore
@@ -0,0 +1,6 @@
+*.env
+/dist
+/**/*.js
+/**/*.js.map
+/**/*.d.ts
+node_modules/
\ No newline at end of file
diff --git a/server/src/routes/__tests__/learningPath.test.ts b/team-bhavitha-dsarecommender/server/.gitkeep
similarity index 100%
rename from server/src/routes/__tests__/learningPath.test.ts
rename to team-bhavitha-dsarecommender/server/.gitkeep
diff --git a/team-bhavitha-dsarecommender/server/app.py b/team-bhavitha-dsarecommender/server/app.py
new file mode 100644
index 000000000..c6ed3fbfb
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/app.py
@@ -0,0 +1,74 @@
+import os
+import json
+import streamlit as st
+import networkx as nx
+
+st.set_page_config(page_title="π Personalized DSA Path", layout="centered")
+
+GRAPH_PATH = "concept_graph_full.json"
+PROFILE_PATH = "learner_profiles.json"
+
+@st.cache_resource
+def load_graph(path):
+ with open(path) as f:
+ data = json.load(f)
+ G = nx.DiGraph()
+ for node in data['nodes']:
+ G.add_node(node['id'], resources=node['resources'])
+ for link in data['links']:
+ G.add_edge(link['source'], link['target'])
+ return G
+
+@st.cache_data
+def load_learner_profiles(path):
+ with open(path) as f:
+ return json.load(f)
+
+try:
+ graph = load_graph(GRAPH_PATH)
+ profiles = load_learner_profiles(PROFILE_PATH)
+ all_nodes = sorted(list(graph.nodes))
+except Exception as e:
+ st.error(f"β Error loading data: {e}")
+
+st.title("π Personalized Learning Path for DSA")
+
+if 'profiles' in locals() and profiles:
+ learner_id = st.selectbox("π Select Learner ID:", [p['learner_id'] for p in profiles])
+ target_concept = st.selectbox("π― Select Target Concept:", all_nodes)
+
+ if st.button("π Recommend Learning Path"):
+ learner = next((l for l in profiles if l["learner_id"] == learner_id), None)
+ if not learner:
+ st.error("Learner not found.")
+ else:
+ mastered = set(learner['mastered_concepts'])
+ weak = set(learner['weak_concepts'])
+ st.write(f"π **Mastered Concepts:** {', '.join(mastered) if mastered else 'None'}")
+ st.write(f"β **Weak Concepts:** {', '.join(weak) if weak else 'None'}")
+
+ min_path = None
+ min_length = float('inf')
+ for start in mastered:
+ if start not in graph:
+ continue
+ if nx.has_path(graph, start, target_concept):
+ try:
+ path = nx.shortest_path(graph, start, target_concept)
+ if len(path) < min_length:
+ min_path = path
+ min_length = len(path)
+ except nx.NetworkXNoPath:
+ continue
+
+ if min_path:
+ st.success(f"β
Recommended Path: {' β '.join(min_path)}")
+ st.info(f"π° Path Length: {len(min_path)}")
+ for concept in min_path:
+ resources = graph.nodes[concept].get("resources", [])
+ for res in resources:
+ st.markdown(f"[π {res['title']}]({res['url']})")
+ else:
+ st.error("β οΈ No path found to the target concept.")
+else:
+ st.warning("β Please ensure the learner_profiles.json and concept_graph_full.json files exist in the same directory as app.py.")
diff --git a/team-bhavitha-dsarecommender/server/authentication/api/auth.ts b/team-bhavitha-dsarecommender/server/authentication/api/auth.ts
new file mode 100644
index 000000000..f439beb25
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/authentication/api/auth.ts
@@ -0,0 +1,5 @@
+// api/[auth].ts
+import app from "../src/main";
+import serverless from "serverless-http";
+
+export default serverless(app);
diff --git a/team-bhavitha-dsarecommender/server/concept_graph_full.json b/team-bhavitha-dsarecommender/server/concept_graph_full.json
new file mode 100644
index 000000000..9d5d386bf
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/concept_graph_full.json
@@ -0,0 +1,171 @@
+{
+ "nodes": [
+ {
+ "id": "Variables",
+ "resources": [
+ {
+ "title": "OCW Lecture: Variables",
+ "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-1/"
+ }
+ ]
+ },
+ {
+ "id": "Loops",
+ "resources": [
+ {
+ "title": "OCW Lecture: Loops",
+ "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-3/"
+ }
+ ]
+ },
+ {
+ "id": "Conditionals",
+ "resources": [
+ {
+ "title": "OCW Lecture: Conditionals",
+ "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-2/"
+ }
+ ]
+ },
+ {
+ "id": "Functions",
+ "resources": [
+ {
+ "title": "OCW Lecture: Functions",
+ "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-4/"
+ }
+ ]
+ },
+ {
+ "id": "Recursion",
+ "resources": [
+ {
+ "title": "OCW Lecture: Recursion",
+ "url": "https://ocw.mit.edu/courses/6-0001/resources/lecture-6/"
+ }
+ ]
+ },
+ {
+ "id": "Arrays",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Arrays",
+ "url": "https://www.geeksforgeeks.org/arrays-in-c-cpp/"
+ }
+ ]
+ },
+ {
+ "id": "Linked Lists",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Linked Lists",
+ "url": "https://www.geeksforgeeks.org/data-structures/linked-list/"
+ }
+ ]
+ },
+ {
+ "id": "Stacks",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Stack Data Structure",
+ "url": "https://www.geeksforgeeks.org/stack-data-structure/"
+ }
+ ]
+ },
+ {
+ "id": "Queues",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Queue Data Structure",
+ "url": "https://www.geeksforgeeks.org/queue-data-structure/"
+ }
+ ]
+ },
+ {
+ "id": "Trees",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Tree Data Structure",
+ "url": "https://www.geeksforgeeks.org/binary-tree-data-structure/"
+ }
+ ]
+ },
+ {
+ "id": "Graphs",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Graph Data Structure",
+ "url": "https://www.geeksforgeeks.org/graph-data-structure-and-algorithms/"
+ }
+ ]
+ },
+ {
+ "id": "Sorting",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Sorting Algorithms",
+ "url": "https://www.geeksforgeeks.org/sorting-algorithms/"
+ }
+ ]
+ },
+ {
+ "id": "Searching",
+ "resources": [
+ {
+ "title": "GeeksforGeeks: Searching Algorithms",
+ "url": "https://www.geeksforgeeks.org/searching-algorithms/"
+ }
+ ]
+ }
+ ],
+ "links": [
+ {
+ "source": "Variables",
+ "target": "Conditionals"
+ },
+ {
+ "source": "Conditionals",
+ "target": "Loops"
+ },
+ {
+ "source": "Loops",
+ "target": "Functions"
+ },
+ {
+ "source": "Functions",
+ "target": "Recursion"
+ },
+ {
+ "source": "Variables",
+ "target": "Arrays"
+ },
+ {
+ "source": "Arrays",
+ "target": "Linked Lists"
+ },
+ {
+ "source": "Linked Lists",
+ "target": "Stacks"
+ },
+ {
+ "source": "Stacks",
+ "target": "Queues"
+ },
+ {
+ "source": "Queues",
+ "target": "Trees"
+ },
+ {
+ "source": "Trees",
+ "target": "Graphs"
+ },
+ {
+ "source": "Graphs",
+ "target": "Sorting"
+ },
+ {
+ "source": "Sorting",
+ "target": "Searching"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/abstraction_04.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/abstraction_04.json
new file mode 100644
index 000000000..661979af1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/abstraction_04.json
@@ -0,0 +1,5 @@
+{
+ "title": "abstraction",
+ "lecture": "04",
+ "content": "Abstraction is the process of hiding details and showing only the essential features of a concept. It helps manage complexity by focusing on what an object does instead of how it does it. In programming, abstraction can be achieved by designing functions or modules with clearly defined inputs and outputs, allowing the internal workings to change without affecting the overall system."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/aliasing_05.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/aliasing_05.json
new file mode 100644
index 000000000..e2c1443a2
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/aliasing_05.json
@@ -0,0 +1,5 @@
+{
+ "title": "aliasing",
+ "lecture": "05",
+ "content": "Aliasing occurs when two variables refer to the same object in memory. Modifying the object through one alias affects the other. For example:\n```python\nx = [1, 2, 3]\ny = x\ny[0] = 9\nprint(x) # Output: [9, 2, 3]\n```\nUnderstanding aliasing is critical for debugging side effects in mutable objects like lists."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/analyzing_loops_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/analyzing_loops_10.json
new file mode 100644
index 000000000..43b809783
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/analyzing_loops_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "analyzing_loops",
+ "lecture": "10",
+ "content": "Analyzing the efficiency of loops involves estimating how many times the loop executes and what work is done inside. Nested loops typically increase complexity. Understanding these patterns helps in calculating Big O complexity."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/assertions_07.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/assertions_07.json
new file mode 100644
index 000000000..07d64dc05
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/assertions_07.json
@@ -0,0 +1,5 @@
+{
+ "title": "assertions",
+ "lecture": "07",
+ "content": "Assertions are used in programming to check if assumptions made in the code are true. In Python, the `assert` statement tests a condition and raises an error if the condition is false. Assertions are helpful for catching bugs early and making the code more robust during development. They should not be used for handling user errors or input validation."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/big_o_notation_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/big_o_notation_10.json
new file mode 100644
index 000000000..447893c9a
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/big_o_notation_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "big_o_notation",
+ "lecture": "10",
+ "content": "Big O notation is used to classify algorithms based on their worst-case growth rate. It provides an upper bound on the time or space used as input size increases. For example, O(n), O(n^2), and O(log n) represent different scaling behaviors."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_variables_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_variables_09.json
new file mode 100644
index 000000000..724160913
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_variables_09.json
@@ -0,0 +1,5 @@
+{
+ "title": "class_variables",
+ "lecture": "09",
+ "content": "Class variables are shared across all instances of a class. The `Rabbit` class uses a class variable `tag` to assign unique IDs to every new instance. This demonstrates how shared state can be managed using class-level data."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_vs_instance_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_vs_instance_09.json
new file mode 100644
index 000000000..a8c1b132d
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/class_vs_instance_09.json
@@ -0,0 +1,5 @@
+{
+ "title": "class_vs_instance",
+ "lecture": "09",
+ "content": "Classes define the structure and behavior for a type of object, while instances are concrete realizations of those classes. The `self` keyword helps refer to individual object instances inside class methods. Each instance has its own data but shares the same method definitions."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/classes_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/classes_08.json
new file mode 100644
index 000000000..6e5af2bde
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/classes_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "classes",
+ "lecture": "08",
+ "content": "Classes define new types in Python using the `class` keyword. A class contains data attributes and procedural attributes (methods). Instances of a class are created using constructors like `__init__`, which initialize the object state."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/cloning_05.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/cloning_05.json
new file mode 100644
index 000000000..60b2b1c92
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/cloning_05.json
@@ -0,0 +1,5 @@
+{
+ "title": "cloning",
+ "lecture": "05",
+ "content": "Cloning refers to creating a copy of a list to avoid aliasing problems. This can be done using slicing:\n```python\noriginal = [1, 2, 3]\nclone = original[:]\n```\nModifying the clone does not affect the original list. Cloning is useful when you need independent copies of mutable objects."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/complexity_classes_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/complexity_classes_10.json
new file mode 100644
index 000000000..98e69b55f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/complexity_classes_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "complexity_classes",
+ "lecture": "10",
+ "content": "Algorithms are grouped into complexity classes based on their growth behavior, such as constant (O(1)), linear (O(n)), quadratic (O(n^2)), etc. This classification helps in selecting efficient algorithms based on expected input sizes."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/debugging_07.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/debugging_07.json
new file mode 100644
index 000000000..7d9a08dcb
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/debugging_07.json
@@ -0,0 +1,5 @@
+{
+ "title": "debugging",
+ "lecture": "07",
+ "content": "Debugging is the process of identifying and correcting errors or bugs in a program. It requires understanding how the program should behave, observing actual behavior, and determining where things go wrong. Common strategies include using print statements, checking variable values, and narrowing down the code responsible for an error. Debugging is as much a reasoning skill as it is technical."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/decomposition_04.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/decomposition_04.json
new file mode 100644
index 000000000..1ddfb9f13
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/decomposition_04.json
@@ -0,0 +1,5 @@
+{
+ "title": "decomposition",
+ "lecture": "04",
+ "content": "Decomposition is the process of breaking a problem into smaller parts to make it more manageable. Each smaller part can be solved independently and combined to solve the entire problem. This promotes modularity and reusability in programming. For example, when designing a program to simulate student grades, you might break the task into separate functions for data input, processing, and output."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/dictionaries_06.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/dictionaries_06.json
new file mode 100644
index 000000000..3f13a73a1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/dictionaries_06.json
@@ -0,0 +1,5 @@
+{
+ "title": "dictionaries",
+ "lecture": "06",
+ "content": "Dictionaries in Python are collections of key-value pairs that provide an efficient way to store and retrieve data. Keys must be immutable and unique, while values can be of any type. Dictionaries allow for fast lookup, insertion, and deletion using operations like `dict[key]`, `in`, and `del`. They are commonly used to count frequencies (e.g., words in lyrics) and improve recursive efficiency by storing intermediate results, such as in memoized Fibonacci functions."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/efficiency_intro_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/efficiency_intro_10.json
new file mode 100644
index 000000000..f8bd009e6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/efficiency_intro_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "efficiency_intro",
+ "lecture": "10",
+ "content": "Efficiency in programming refers to writing code that runs within reasonable time and memory limits. It is important when dealing with large-scale problems. Measuring and improving program efficiency involves understanding computational cost and performance trade-offs."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/exceptions_07.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/exceptions_07.json
new file mode 100644
index 000000000..c118e26bd
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/exceptions_07.json
@@ -0,0 +1,5 @@
+{
+ "title": "exceptions",
+ "lecture": "07",
+ "content": "Exceptions are errors that occur during program execution, such as dividing by zero or accessing an invalid index. Python provides mechanisms to handle exceptions gracefully using `try`, `except`, and `finally` blocks. Proper exception handling ensures a program can recover from unexpected events without crashing."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/fraction_example_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/fraction_example_08.json
new file mode 100644
index 000000000..306d8955f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/fraction_example_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "fraction_example",
+ "lecture": "08",
+ "content": "The Fraction example shows how to create a new number type with its own internal representation (numerator, denominator) and methods (add, subtract, convert, invert). It demonstrates the full power of OOP in modeling real-world objects."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/functions_04.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/functions_04.json
new file mode 100644
index 000000000..5d4745bce
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/functions_04.json
@@ -0,0 +1,5 @@
+{
+ "title": "functions",
+ "lecture": "04",
+ "content": "Functions are reusable blocks of code that perform a specific task. They are defined using the `def` keyword followed by the function name and parentheses with optional parameters. Functions can return values using the `return` statement. This promotes code reuse, testing, and logical organization.\n\nExample:\ndef square(x):\n return x * x"
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/getters_setters_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/getters_setters_09.json
new file mode 100644
index 000000000..ae5ec6613
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/getters_setters_09.json
@@ -0,0 +1,5 @@
+{
+ "title": "getters_setters",
+ "lecture": "09",
+ "content": "Getters and setters are methods used to access and modify object data. They promote good software design by hiding internal data representation and preventing direct attribute modification. Default arguments can be used in setters for flexible usage."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/information_hiding_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/information_hiding_09.json
new file mode 100644
index 000000000..1b67cd063
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/information_hiding_09.json
@@ -0,0 +1,6 @@
+{
+ "title": "information_hiding",
+ "lecture": "09",
+ "content": "Information hiding protects internal implementation details of a class. Accessing or modifying attributes directly from outside the class can cause bugs if the internal structure changes. Using getters and setters helps avoid this and improves code maintainability."
+}
+
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_basics_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_basics_09.json
new file mode 100644
index 000000000..21ee838f5
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_basics_09.json
@@ -0,0 +1,5 @@
+{
+ "title": "inheritance_basics",
+ "lecture": "09",
+ "content": "Inheritance allows a class (subclass) to inherit properties and methods from another class (superclass). It helps reduce redundancy and supports hierarchical relationships in object modeling. Python subclasses can override or extend inherited behavior."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_subclass_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_subclass_09.json
new file mode 100644
index 000000000..f2c2a46d5
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/inheritance_subclass_09.json
@@ -0,0 +1,6 @@
+{
+ "title": "inheritance_subclass",
+ "lecture": "09",
+ "content": "Subclasses like `Cat`, `Person`, and `Student` inherit from a parent class `Animal`. They can define their own `__init__` methods and override existing methods like `__str__` and `speak`. This shows polymorphism in action, where different subclasses behave differently even when using inherited structure."
+}
+
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/linear_complexity_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/linear_complexity_10.json
new file mode 100644
index 000000000..44949e22c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/linear_complexity_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "linear_complexity",
+ "lecture": "10",
+ "content": "Linear complexity (O(n)) describes algorithms whose run time increases proportionally with input size. A single loop iterating over an input is a common example. These algorithms scale well and are generally considered efficient for large inputs."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/methods_and_self_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/methods_and_self_08.json
new file mode 100644
index 000000000..34f66fc4d
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/methods_and_self_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "methods_and_self",
+ "lecture": "08",
+ "content": "Methods are functions that belong to a class. In Python, the first parameter of any method is `self`, which refers to the instance. Methods use dot notation and interact with instance variables to define behavior unique to that object."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/mutability_05.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/mutability_05.json
new file mode 100644
index 000000000..242cf3993
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/mutability_05.json
@@ -0,0 +1,5 @@
+{
+ "title": "mutability",
+ "lecture": "05",
+ "content": "Mutability refers to whether an objectβs contents can be changed after creation. Lists are mutable, while tuples are not. Mutable objects can cause unexpected side effects when shared between parts of a program. Understanding mutability is essential for managing data flow, debugging, and writing robust functions."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/nested_loops_summary_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/nested_loops_summary_10.json
new file mode 100644
index 000000000..20c90cd3a
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/nested_loops_summary_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "nested_loops_summary",
+ "lecture": "10",
+ "content": "Nested loops significantly affect complexity. The total operations multiply based on loop nesting. Efficient programming involves identifying when nested loops can be reduced, optimized, or avoided altogether."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/objects_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/objects_08.json
new file mode 100644
index 000000000..bef50a0d1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/objects_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "objects",
+ "lecture": "08",
+ "content": "In Python, everything is an object β integers, floats, strings, lists, dictionaries. Each object has a type, internal representation, and methods to interact with it. Understanding that data and behavior are bundled into objects is the foundation for OOP in Python."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_basics_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_basics_08.json
new file mode 100644
index 000000000..c1b6202c1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_basics_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "oop_basics",
+ "lecture": "08",
+ "content": "Object-Oriented Programming (OOP) abstracts behavior through interfaces and encapsulates internal data. Benefits include modularity, reusability, and the ability to build complex systems by combining smaller, manageable units β objects."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_power_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_power_08.json
new file mode 100644
index 000000000..bd87c11a7
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_power_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "oop_power",
+ "lecture": "08",
+ "content": "OOP enables abstraction, encapsulation, and inheritance. It allows developers to build reusable, layered systems where complex behaviors are composed of simpler objects working together. This is a fundamental principle in scalable software design."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_summary_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_summary_09.json
new file mode 100644
index 000000000..c7d8d8c51
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/oop_summary_09.json
@@ -0,0 +1,6 @@
+{
+ "title": "oop_summary",
+ "lecture": "09",
+ "content": "Object-Oriented Programming (OOP) supports data encapsulation, abstraction, and modularity. It organizes data and functions together into classes, making programs easier to manage and extend. Classes allow decomposition of tasks into manageable components."
+}
+
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/operator_overloading_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/operator_overloading_08.json
new file mode 100644
index 000000000..bff957db0
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/operator_overloading_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "operator_overloading",
+ "lecture": "08",
+ "content": "Python lets you redefine how operators like `+`, `==`, or `len()` behave using special methods like `__add__`, `__eq__`, `__len__`, etc. This allows your custom classes to behave like built-in types."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/orders_of_growth_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/orders_of_growth_10.json
new file mode 100644
index 000000000..97d4acc28
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/orders_of_growth_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "orders_of_growth",
+ "lecture": "10",
+ "content": "Orders of growth describe how the run time or space requirements of an algorithm scale with input size. Common growth classes include constant, logarithmic, linear, quadratic, and exponential. These help predict how programs behave as inputs grow."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/quadratic_complexity_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/quadratic_complexity_10.json
new file mode 100644
index 000000000..d6c3b94c6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/quadratic_complexity_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "quadratic_complexity",
+ "lecture": "10",
+ "content": "Quadratic complexity (O(n^2)) occurs when an algorithm performs a nested iteration over input. For large inputs, this becomes inefficient quickly. Bubble sort is a classic example of an O(n^2) algorithm."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/rabbit_example_09.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/rabbit_example_09.json
new file mode 100644
index 000000000..995b8ce96
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/rabbit_example_09.json
@@ -0,0 +1,5 @@
+{
+ "title": "rabbit_example",
+ "lecture": "09",
+ "content": "The `Rabbit` class showcases operator overloading (`__add__`) to allow two rabbits to create a child. The `__eq__` method is overridden to define equality based on the parentsβ IDs. This example highlights inheritance, overloading, and identity-based comparison."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/recursion_06.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/recursion_06.json
new file mode 100644
index 000000000..85d6c9be4
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/recursion_06.json
@@ -0,0 +1,6 @@
+{
+ "title": "recursion",
+ "lecture": "06",
+ "content": "Recursion is a method of solving problems by breaking them into smaller, self-similar problems. A recursive function calls itself with a simpler input until it reaches a base case. Common recursive examples include multiplication, factorial, Fibonacci, palindrome checking, and the Towers of Hanoi. Recursion requires careful control of scope and termination conditions to avoid infinite loops and stack overflows."
+}
+
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/scope_04.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/scope_04.json
new file mode 100644
index 000000000..15ed1aed3
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/scope_04.json
@@ -0,0 +1,5 @@
+{
+ "title": "scope",
+ "lecture": "04",
+ "content": "Scope defines where a variable can be accessed in a program. Variables declared inside a function are local to that function and cannot be accessed outside. Global variables, on the other hand, can be accessed throughout the entire program. Python also allows nested functions, where inner functions can access variables from enclosing functions (nonlocal scope). Understanding scope is critical to avoid bugs and manage data flow between parts of a program."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/str_method_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/str_method_08.json
new file mode 100644
index 000000000..7a513d3c2
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/str_method_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "str_method",
+ "lecture": "08",
+ "content": "The `__str__` method defines how an object appears when printed. Without it, Python prints a default memory address. By overriding `__str__`, developers can create readable, meaningful string representations of custom objects."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/testing_07.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/testing_07.json
new file mode 100644
index 000000000..37530d801
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/testing_07.json
@@ -0,0 +1,5 @@
+{
+ "title": "testing",
+ "lecture": "07",
+ "content": "Testing is a critical part of writing high-quality programs. It helps identify errors early and ensures that code behaves as expected. Testing types include black-box testing (focusing on inputs and outputs) and white-box testing (understanding internal code paths). Good testing requires thinking of edge cases and checking whether functions produce correct results under various scenarios."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/timing_vs_counting_10.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/timing_vs_counting_10.json
new file mode 100644
index 000000000..d456324b6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/timing_vs_counting_10.json
@@ -0,0 +1,5 @@
+{
+ "title": "timing_vs_counting",
+ "lecture": "10",
+ "content": "Measuring program performance can be done by timing actual execution or by counting basic operations (steps). While timing is practical, it can vary by system. Counting operations gives a more stable, system-independent measure of algorithm complexity."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/tuples_05.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/tuples_05.json
new file mode 100644
index 000000000..c2577757a
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/tuples_05.json
@@ -0,0 +1,5 @@
+{
+ "title": "tuples",
+ "lecture": "05",
+ "content": "Tuples are immutable sequences in Python used to store collections of items. They are defined using parentheses: `t = (1, 2, 3)`. Tuples support indexing, slicing, and iteration just like lists, but their contents cannot be changed after creation. They are often used for fixed-size, heterogeneous data and function return values where immutability is desired."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/types_and_instances_08.json b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/types_and_instances_08.json
new file mode 100644
index 000000000..5db96b87e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/json_output/types_and_instances_08.json
@@ -0,0 +1,5 @@
+{
+ "title": "types_and_instances",
+ "lecture": "08",
+ "content": "You can inspect objects using `type()` and verify membership with `isinstance()`. These introspection tools are useful in debugging and in ensuring objects behave as expected within class hierarchies."
+}
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_04.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_04.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_04.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_05.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_05.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_05.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_06.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_06.pdf
new file mode 100644
index 000000000..99ff9cc40
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_06.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_07.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_07.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_07.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_09.pdf
new file mode 100644
index 000000000..01e519b2d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/mit_pdfs/lecture_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/abstraction_04.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/abstraction_04.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/abstraction_04.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/aliasing_05.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/aliasing_05.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/aliasing_05.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/analyzing_loops_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/analyzing_loops_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/analyzing_loops_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/assertions_07.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/assertions_07.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/assertions_07.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/big_o_notation_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/big_o_notation_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/big_o_notation_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_variables_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_variables_09.pdf
new file mode 100644
index 000000000..869ec6161
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_variables_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_vs_instance_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_vs_instance_09.pdf
new file mode 100644
index 000000000..a7e37c80d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/class_vs_instance_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/classes_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/classes_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/classes_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/cloning_05.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/cloning_05.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/cloning_05.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/complexity_classes_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/complexity_classes_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/complexity_classes_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/debugging_07.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/debugging_07.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/debugging_07.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/decomposition_04.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/decomposition_04.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/decomposition_04.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/dictionaries_06.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/dictionaries_06.pdf
new file mode 100644
index 000000000..99ff9cc40
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/dictionaries_06.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/efficiency_intro_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/efficiency_intro_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/efficiency_intro_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/exceptions_07.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/exceptions_07.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/exceptions_07.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/fraction_example_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/fraction_example_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/fraction_example_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/functions_04.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/functions_04.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/functions_04.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/getters_setters_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/getters_setters_09.pdf
new file mode 100644
index 000000000..123e0f172
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/getters_setters_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/information_hiding_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/information_hiding_09.pdf
new file mode 100644
index 000000000..4b0615c0b
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/information_hiding_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_basics_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_basics_09.pdf
new file mode 100644
index 000000000..1238b4926
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_basics_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_subclass_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_subclass_09.pdf
new file mode 100644
index 000000000..b8933edb8
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/inheritance_subclass_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/linear_complexity_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/linear_complexity_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/linear_complexity_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/lists_05.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/lists_05.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/lists_05.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/methods_and_self_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/methods_and_self_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/methods_and_self_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/nested_loops_summary_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/nested_loops_summary_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/nested_loops_summary_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/objects_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/objects_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/objects_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_power_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_power_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_power_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_summary_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_summary_09.pdf
new file mode 100644
index 000000000..eaa33da6c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/oop_summary_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/operator_overloading_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/operator_overloading_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/operator_overloading_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/orders_of_growth_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/orders_of_growth_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/orders_of_growth_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/quadratic_complexity_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/quadratic_complexity_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/quadratic_complexity_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/rabbit_example_09.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/rabbit_example_09.pdf
new file mode 100644
index 000000000..b1b2244b0
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/rabbit_example_09.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/recursion_06.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/recursion_06.pdf
new file mode 100644
index 000000000..99ff9cc40
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/recursion_06.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/scope_04.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/scope_04.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/scope_04.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/str_method_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/str_method_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/str_method_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/testing_07.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/testing_07.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/testing_07.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/timing_vs_counting_10.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/timing_vs_counting_10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/timing_vs_counting_10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/tuples_05.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/tuples_05.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/tuples_05.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/types_and_instances_08.pdf b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/types_and_instances_08.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/data/MIT_OCW_Scraper/pdfs/types_and_instances_08.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/learner_profiles.json b/team-bhavitha-dsarecommender/server/learner_profiles.json
new file mode 100644
index 000000000..f0cb981ba
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/learner_profiles.json
@@ -0,0 +1,501 @@
+[
+ {
+ "learner_id": "L001",
+ "mastered_concepts": [
+ "Computation",
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L002",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L003",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L004",
+ "mastered_concepts": [
+ "Variables",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L005",
+ "mastered_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L006",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L007",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L008",
+ "mastered_concepts": [
+ "Variables",
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L009",
+ "mastered_concepts": [
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L010",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L011",
+ "mastered_concepts": [
+ "Variables",
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Computation",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L012",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L013",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L014",
+ "mastered_concepts": [
+ "Variables",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L015",
+ "mastered_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L016",
+ "mastered_concepts": [
+ "Computation",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L017",
+ "mastered_concepts": [
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L018",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L019",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Loops",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L020",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L021",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L022",
+ "mastered_concepts": [
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L023",
+ "mastered_concepts": [
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L024",
+ "mastered_concepts": [
+ "Computation",
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L025",
+ "mastered_concepts": [
+ "Computation"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L026",
+ "mastered_concepts": [
+ "Variables",
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L027",
+ "mastered_concepts": [
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L028",
+ "mastered_concepts": [
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L029",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Computation",
+ "Loops",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L030",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L031",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L032",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Computation",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L033",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Loops",
+ "Computation",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L034",
+ "mastered_concepts": [
+ "Computation",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Variables",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L035",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Loops",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L036",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L037",
+ "mastered_concepts": [
+ "Loops",
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L038",
+ "mastered_concepts": [
+ "Computation",
+ "Loops",
+ "Variables"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L039",
+ "mastered_concepts": [
+ "Variables",
+ "Computation",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L040",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L041",
+ "mastered_concepts": [
+ "Variables",
+ "Computation"
+ ],
+ "weak_concepts": [
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L042",
+ "mastered_concepts": [
+ "Variables",
+ "Computation",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Variables",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L043",
+ "mastered_concepts": [
+ "Variables",
+ "Loops",
+ "Computation"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L044",
+ "mastered_concepts": [
+ "Variables",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Loops"
+ ]
+ },
+ {
+ "learner_id": "L045",
+ "mastered_concepts": [],
+ "weak_concepts": [
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L046",
+ "mastered_concepts": [
+ "Variables",
+ "Computation",
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Loops",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L047",
+ "mastered_concepts": [
+ "Computation"
+ ],
+ "weak_concepts": []
+ },
+ {
+ "learner_id": "L048",
+ "mastered_concepts": [
+ "Computation",
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation"
+ ]
+ },
+ {
+ "learner_id": "L049",
+ "mastered_concepts": [
+ "Loops"
+ ],
+ "weak_concepts": [
+ "Loops",
+ "Computation",
+ "Variables"
+ ]
+ },
+ {
+ "learner_id": "L050",
+ "mastered_concepts": [
+ "Variables"
+ ],
+ "weak_concepts": [
+ "Computation",
+ "Loops",
+ "Variables"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/package-lock.json b/team-bhavitha-dsarecommender/server/package-lock.json
new file mode 100644
index 000000000..1922cae69
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/package-lock.json
@@ -0,0 +1,4115 @@
+{
+ "name": "server",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "server",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@google/genai": "^1.7.0",
+ "@google/generative-ai": "^0.24.1",
+ "axios": "^1.10.0",
+ "bcrypt": "^6.0.0",
+ "bcryptjs": "^3.0.2",
+ "compromise": "^14.14.4",
+ "compromise-sentences": "^0.3.0",
+ "cors": "^2.8.5",
+ "dotenv": "^16.5.0",
+ "express": "^5.1.0",
+ "gridfs-stream": "^1.1.1",
+ "jsonwebtoken": "^9.0.2",
+ "mongoose": "^8.16.0",
+ "multer": "^1.4.4",
+ "multer-gridfs-storage": "^5.0.2",
+ "natural": "^8.1.0",
+ "node-summarizer": "^1.0.7",
+ "openai": "^5.3.0",
+ "pdf-parse": "^1.1.1",
+ "serverless-http": "^3.2.0",
+ "socket.io": "^4.8.1"
+ },
+ "devDependencies": {
+ "@types/axios": "^0.9.36",
+ "@types/bcryptjs": "^2.4.6",
+ "@types/body-parser": "^1.19.6",
+ "@types/cors": "^2.8.19",
+ "@types/express": "^5.0.3",
+ "@types/jsonwebtoken": "^9.0.10",
+ "@types/mongoose": "^5.11.96",
+ "@types/node": "^24.0.10",
+ "@types/pdf-parse": "^1.1.5",
+ "ts-node-dev": "^2.0.0",
+ "typescript": "^5.8.3"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@google/genai": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.7.0.tgz",
+ "integrity": "sha512-s/OZLkrIfBwc+SFFaZoKdEogkw4in0YRTGc4Q483jnfchNBWzrNe560eZEfGJHQRPn6YfzJgECCx0sqEOMWvYw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "google-auth-library": "^9.14.2",
+ "ws": "^8.18.0",
+ "zod": "^3.22.4",
+ "zod-to-json-schema": "^3.22.4"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "@modelcontextprotocol/sdk": "^1.11.0"
+ },
+ "peerDependenciesMeta": {
+ "@modelcontextprotocol/sdk": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@google/generative-ai": {
+ "version": "0.24.1",
+ "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
+ "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@mongodb-js/saslprep": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz",
+ "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ }
+ },
+ "node_modules/@redis/bloom": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
+ "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
+ "integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
+ "license": "MIT",
+ "dependencies": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
+ "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
+ "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
+ "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
+ "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@socket.io/component-emitter": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/axios": {
+ "version": "0.9.36",
+ "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.9.36.tgz",
+ "integrity": "sha512-NLOpedx9o+rxo/X5ChbdiX6mS1atE4WHmEEIcR9NLenRVa5HoVjAvjafwU3FPTqnZEstpoqCaW7fagqSoTDNeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/bcryptjs": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz",
+ "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.6",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
+ "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/bson": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz",
+ "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/cors": {
+ "version": "2.8.19",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
+ "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/express": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz",
+ "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^5.0.0",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
+ "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
+ "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/jsonwebtoken": {
+ "version": "9.0.10",
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
+ "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "license": "MIT"
+ },
+ "node_modules/@types/mongodb": {
+ "version": "3.6.20",
+ "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz",
+ "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/bson": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/mongoose": {
+ "version": "5.11.96",
+ "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.11.96.tgz",
+ "integrity": "sha512-keiY22ljJtXyM7osgScmZOHV6eL5VFUD5tQumlu+hjS++HND5nM8jNEdj5CSWfKIJpVwQfPuwQ2SfBqUnCAVRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mongoose": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/multer": {
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.13.tgz",
+ "integrity": "sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "24.0.10",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz",
+ "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.8.0"
+ }
+ },
+ "node_modules/@types/pdf-parse": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@types/pdf-parse/-/pdf-parse-1.1.5.tgz",
+ "integrity": "sha512-kBfrSXsloMnUJOKi25s3+hRmkycHfLK6A09eRGqF/N8BkQoPUmaCr+q8Cli5FnfohEz/rsv82zAiPz/LXtOGhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/pump": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@types/pump/-/pump-1.1.3.tgz",
+ "integrity": "sha512-ZyooTTivmOwPfOwLVaszkF8Zq6mvavgjuHYitZhrIjfQAJDH+kIP3N+MzpG1zDAslsHvVz6Q8ECfivix3qLJaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/send": {
+ "version": "0.17.5",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz",
+ "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz",
+ "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/strip-json-comments": {
+ "version": "0.0.30",
+ "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
+ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/webidl-conversions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
+ "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/whatwg-url": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
+ "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/webidl-conversions": "*"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/afinn-165": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/afinn-165/-/afinn-165-1.0.4.tgz",
+ "integrity": "sha512-7+Wlx3BImrK0HiG6y3lU4xX7SpBPSSu8T9iguPMlaueRFxjbYwAQrp9lqZUuFikqKbd/en8lVREILvP2J80uJA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/afinn-165-financialmarketnews": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/afinn-165-financialmarketnews/-/afinn-165-financialmarketnews-3.0.0.tgz",
+ "integrity": "sha512-0g9A1S3ZomFIGDTzZ0t6xmv4AuokBvBmpes8htiyHpH7N4xDmvSQL6UxL/Zcs2ypRb3VwgCscaD8Q3zEawKYhw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/apparatus": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/apparatus/-/apparatus-0.0.10.tgz",
+ "integrity": "sha512-KLy/ugo33KZA7nugtQ7O0E1c8kQ52N3IvD/XgIh4w/Nr28ypfkwDfA67F1ev4N1m5D+BOk1+b2dEJDfpj/VvZg==",
+ "license": "MIT",
+ "dependencies": {
+ "sylvester": ">= 0.0.8"
+ },
+ "engines": {
+ "node": ">=0.2.6"
+ }
+ },
+ "node_modules/append-field": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
+ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
+ "license": "MIT"
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
+ "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/base64id": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+ "license": "MIT",
+ "engines": {
+ "node": "^4.5.0 || >= 5.9"
+ }
+ },
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/bcrypt": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz",
+ "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-addon-api": "^8.3.0",
+ "node-gyp-build": "^4.8.4"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/bcryptjs": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
+ "integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
+ "license": "BSD-3-Clause",
+ "bin": {
+ "bcrypt": "bin/bcrypt"
+ }
+ },
+ "node_modules/bignumber.js": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.0.tgz",
+ "integrity": "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
+ "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.0",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.6.3",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.0",
+ "type-is": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bson": {
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
+ "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.20.1"
+ }
+ },
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT"
+ },
+ "node_modules/busboy": {
+ "version": "0.2.14",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
+ "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
+ "dependencies": {
+ "dicer": "0.2.5",
+ "readable-stream": "1.1.x"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "license": "MIT"
+ },
+ "node_modules/compromise": {
+ "version": "14.14.4",
+ "resolved": "https://registry.npmjs.org/compromise/-/compromise-14.14.4.tgz",
+ "integrity": "sha512-QdbJwronwxeqb7a5KFK/+Y5YieZ4PE1f7ai0vU58Pp4jih+soDCBMuKVbhDEPQ+6+vI3vSiG4UAAjTAXLJw1Qw==",
+ "license": "MIT",
+ "dependencies": {
+ "efrt": "2.7.0",
+ "grad-school": "0.0.5",
+ "suffix-thumb": "5.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/compromise-sentences": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/compromise-sentences/-/compromise-sentences-0.3.0.tgz",
+ "integrity": "sha512-L6d5PXmmyPyWRMoJURYOM0yILhtV37zCOy9ZW8Xd6KgY+2qQBTwuokekaGL9MDpSH3/grRDL+AHKytYpGrTEmA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "compromise": ">=12.0.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "engines": [
+ "node >= 0.8"
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "node_modules/concat-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
+ "node_modules/concat-stream/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/concat-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/concat-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/corser": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
+ "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/dicer": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
+ "integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
+ "dependencies": {
+ "readable-stream": "1.1.x",
+ "streamsearch": "0.1.2"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.5.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
+ "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/dynamic-dedupe": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
+ "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ }
+ },
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/efrt": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/efrt/-/efrt-2.7.0.tgz",
+ "integrity": "sha512-/RInbCy1d4P6Zdfa+TMVsf/ufZVotat5hCw3QXmWtjU+3pFEOvOQ7ibo3aIxyCJw2leIeAMjmPj+1SLJiCpdrQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
+ "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/engine.io": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
+ "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/cors": "^2.8.12",
+ "@types/node": ">=10.0.0",
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.7.2",
+ "cors": "~2.8.5",
+ "debug": "~4.3.1",
+ "engine.io-parser": "~5.2.1",
+ "ws": "~8.17.1"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/engine.io-parser": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+ "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/engine.io/node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/engine.io/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/engine.io/node_modules/ws": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "license": "MIT"
+ },
+ "node_modules/express": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
+ "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.0",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/flushwritable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/flushwritable/-/flushwritable-1.0.0.tgz",
+ "integrity": "sha512-3VELfuWCLVzt5d2Gblk8qcqFro6nuwvxwMzHaENVDHI7rxcBRtMCwTk/E9FXcgh+82DSpavPNDueA9+RxXJoFg==",
+ "license": "MIT"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
+ "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/form-data/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/form-data/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gaxios": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
+ "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^7.0.1",
+ "is-stream": "^2.0.0",
+ "node-fetch": "^2.6.9",
+ "uuid": "^9.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/gcp-metadata": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
+ "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "gaxios": "^5.0.0",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/gcp-metadata/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/gcp-metadata/node_modules/gaxios": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz",
+ "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^5.0.0",
+ "is-stream": "^2.0.0",
+ "node-fetch": "^2.6.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/gcp-metadata/node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/generic-pool": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
+ "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/google-auth-library": {
+ "version": "9.15.1",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz",
+ "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "gaxios": "^6.1.1",
+ "gcp-metadata": "^6.1.0",
+ "gtoken": "^7.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/google-auth-library/node_modules/gcp-metadata": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz",
+ "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "gaxios": "^6.1.1",
+ "google-logging-utils": "^0.0.2",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/google-logging-utils": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz",
+ "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/grad-school": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/grad-school/-/grad-school-0.0.5.tgz",
+ "integrity": "sha512-rXunEHF9M9EkMydTBux7+IryYXEZinRk6g8OBOGDBzo/qWJjhTxy86i5q7lQYpCLHN8Sqv1XX3OIOc7ka2gtvQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/gridfs-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/gridfs-stream/-/gridfs-stream-1.1.1.tgz",
+ "integrity": "sha512-EcELdPIjC7tpZUiZA/8trfmszLbcsZlFyDQ8DhMtyJIMDmuLi5Vzt/056OO6FqfvY/zwiTCo1eZAqwtqrhBGMQ==",
+ "dependencies": {
+ "flushwritable": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4.2"
+ }
+ },
+ "node_modules/gtoken": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
+ "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
+ "license": "MIT",
+ "dependencies": {
+ "gaxios": "^6.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-own-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
+ "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+ "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-errors/node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-server": {
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
+ "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
+ "license": "MIT",
+ "dependencies": {
+ "basic-auth": "^2.0.1",
+ "chalk": "^4.1.2",
+ "corser": "^2.0.1",
+ "he": "^1.2.0",
+ "html-encoding-sniffer": "^3.0.0",
+ "http-proxy": "^1.18.1",
+ "mime": "^1.6.0",
+ "minimist": "^1.2.6",
+ "opener": "^1.5.1",
+ "portfinder": "^1.0.28",
+ "secure-compare": "3.0.1",
+ "union": "~0.5.0",
+ "url-join": "^4.0.1"
+ },
+ "bin": {
+ "http-server": "bin/http-server"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-generator": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz",
+ "integrity": "sha512-G56jBpbJeg7ds83HW1LuShNs8J73Fv3CPz/bmROHOHlnKkN8sWb9ujiagjmxxMUywftgq48HlBZELKKqFLk0oA==",
+ "license": "MIT"
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
+ "license": "MIT"
+ },
+ "node_modules/json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "node_modules/json-stable-stringify": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz",
+ "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "isarray": "^2.0.5",
+ "jsonify": "^0.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/json-stable-stringify/node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "license": "MIT"
+ },
+ "node_modules/jsonify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
+ "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
+ "license": "Public Domain",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/jsonwebtoken/node_modules/jwa": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jsonwebtoken/node_modules/jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
+ "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
+ "license": "MIT",
+ "dependencies": {
+ "jwa": "^2.0.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/kareem": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "license": "MIT"
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/memjs": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/memjs/-/memjs-1.3.2.tgz",
+ "integrity": "sha512-qUEg2g8vxPe+zPn09KidjIStHPtoBO8Cttm8bgJFWWabbsjQ9Av9Ky+6UcvKx6ue0LLb/LEhtcyQpRyKfzeXcg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "license": "MIT"
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mongodb": {
+ "version": "6.17.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.17.0.tgz",
+ "integrity": "sha512-neerUzg/8U26cgruLysKEjJvoNSXhyID3RvzvdcpsIi2COYM3FS3o9nlH7fxFtefTb942dX3W9i37oPfCVj4wA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@mongodb-js/saslprep": "^1.1.9",
+ "bson": "^6.10.4",
+ "mongodb-connection-string-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "peerDependencies": {
+ "@aws-sdk/credential-providers": "^3.188.0",
+ "@mongodb-js/zstd": "^1.1.0 || ^2.0.0",
+ "gcp-metadata": "^5.2.0",
+ "kerberos": "^2.0.1",
+ "mongodb-client-encryption": ">=6.0.0 <7",
+ "snappy": "^7.2.2",
+ "socks": "^2.7.1"
+ },
+ "peerDependenciesMeta": {
+ "@aws-sdk/credential-providers": {
+ "optional": true
+ },
+ "@mongodb-js/zstd": {
+ "optional": true
+ },
+ "gcp-metadata": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ },
+ "socks": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/mongodb-connection-string-url": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz",
+ "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/whatwg-url": "^11.0.2",
+ "whatwg-url": "^14.1.0 || ^13.0.0"
+ }
+ },
+ "node_modules/mongodb-uri": {
+ "version": "0.9.7",
+ "resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz",
+ "integrity": "sha512-s6BdnqNoEYfViPJgkH85X5Nw5NpzxN8hoflKLweNa7vBxt2V7kaS06d74pAtqDxde8fn4r9h4dNdLiFGoNV0KA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/mongoose": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.16.0.tgz",
+ "integrity": "sha512-gLuAZsbwY0PHjrvfuXvUkUq9tXjyAjN3ioXph5Y6Seu7/Uo8xJaM+rrMbL/x34K4T3UTgtXRyfoq1YU16qKyIw==",
+ "license": "MIT",
+ "dependencies": {
+ "bson": "^6.10.4",
+ "kareem": "2.6.3",
+ "mongodb": "~6.17.0",
+ "mpath": "0.9.0",
+ "mquery": "5.0.0",
+ "ms": "2.1.3",
+ "sift": "17.1.3"
+ },
+ "engines": {
+ "node": ">=16.20.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mongoose"
+ }
+ },
+ "node_modules/mpath": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz",
+ "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/mquery": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz",
+ "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4.x"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/multer": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
+ "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
+ "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
+ "license": "MIT",
+ "dependencies": {
+ "append-field": "^1.0.0",
+ "busboy": "^0.2.11",
+ "concat-stream": "^1.5.2",
+ "mkdirp": "^0.5.4",
+ "object-assign": "^4.1.1",
+ "on-finished": "^2.3.0",
+ "type-is": "^1.6.4",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/multer-gridfs-storage": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/multer-gridfs-storage/-/multer-gridfs-storage-5.0.2.tgz",
+ "integrity": "sha512-oYl70i792uyJfgpvOfJrZIru4MsjjAueDHLZXTDGix/yPJuk1/lfqdPHHnv/XVVGfVZb4G9jJqwEFf9JIX1SOQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "^4.17.6",
+ "@types/mongodb": "^3.5.25",
+ "@types/multer": "^1.4.3",
+ "@types/pump": "^1.1.0",
+ "has-own-prop": "^2.0.0",
+ "is-generator": "^1.0.3",
+ "is-promise": "^4.0.0",
+ "lodash.isplainobject": ">=0.8.0",
+ "mongodb": ">=2",
+ "mongodb-uri": "^0.9.7",
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "multer": "^1.4.2"
+ }
+ },
+ "node_modules/multer-gridfs-storage/node_modules/@types/express": {
+ "version": "4.17.23",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz",
+ "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/multer-gridfs-storage/node_modules/@types/express-serve-static-core": {
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/multer/node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/multer/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/multer/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/multer/node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "license": "MIT",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/natural": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/natural/-/natural-8.1.0.tgz",
+ "integrity": "sha512-qHKU+BzPXzEDwToFBzlI+3oI2jeN3xRNP421ifoF2Fw7ej+5zEO3Z5wUKPjz00jhz9/ESerIUGfhPqqkOqlWPA==",
+ "license": "MIT",
+ "dependencies": {
+ "afinn-165": "^1.0.2",
+ "afinn-165-financialmarketnews": "^3.0.0",
+ "apparatus": "^0.0.10",
+ "dotenv": "^16.4.5",
+ "http-server": "^14.1.1",
+ "memjs": "^1.3.2",
+ "mongoose": "^8.2.0",
+ "pg": "^8.11.3",
+ "redis": "^4.6.13",
+ "safe-stable-stringify": "^2.2.0",
+ "stopwords-iso": "^1.1.0",
+ "sylvester": "^0.0.12",
+ "underscore": "^1.9.1",
+ "uuid": "^9.0.1",
+ "wordnet-db": "^3.1.11"
+ },
+ "engines": {
+ "node": ">=0.4.10"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
+ "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
+ "license": "MIT",
+ "engines": {
+ "node": "^18 || ^20 || >= 21"
+ }
+ },
+ "node_modules/node-ensure": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
+ "integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==",
+ "license": "MIT"
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/node-summarizer": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/node-summarizer/-/node-summarizer-1.0.7.tgz",
+ "integrity": "sha512-kHgVyhm+k97/50ActxLFIemHLvYPwHLJfwF3tEg2TqeL5xmUCCytqRwdiO3LyBRFMUopLJjisSlkJwTk72gVbg==",
+ "license": "ISC",
+ "dependencies": {
+ "natural": "^0.6.3",
+ "wordpos": "^1.2.0"
+ }
+ },
+ "node_modules/node-summarizer/node_modules/natural": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/natural/-/natural-0.6.3.tgz",
+ "integrity": "sha512-78fcEdNN6Y4pv8SOLPDhJTlUG+8IiQzNx0nYpl0k7q00K4ZZuds+wDWfSa6eeiPcSQDncvV44WWGsi70/ZP3+w==",
+ "license": "MIT",
+ "dependencies": {
+ "afinn-165": "^1.0.2",
+ "apparatus": "^0.0.10",
+ "json-stable-stringify": "^1.0.1",
+ "sylvester": "^0.0.12",
+ "underscore": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=0.4.10"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/openai": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-5.7.0.tgz",
+ "integrity": "sha512-zXWawZl6J/P5Wz57/nKzVT3kJQZvogfuyuNVCdEp4/XU2UNrjL7SsuNpWAyLZbo6HVymwmnfno9toVzBhelygA==",
+ "license": "Apache-2.0",
+ "bin": {
+ "openai": "bin/cli"
+ },
+ "peerDependencies": {
+ "ws": "^8.18.0",
+ "zod": "^3.23.8"
+ },
+ "peerDependenciesMeta": {
+ "ws": {
+ "optional": true
+ },
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "license": "(WTFPL OR MIT)",
+ "bin": {
+ "opener": "bin/opener-bin.js"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
+ "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/pdf-parse": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz",
+ "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^3.1.0",
+ "node-ensure": "^0.0.0"
+ },
+ "engines": {
+ "node": ">=6.8.1"
+ }
+ },
+ "node_modules/pdf-parse/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/pg": {
+ "version": "8.16.3",
+ "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
+ "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
+ "license": "MIT",
+ "dependencies": {
+ "pg-connection-string": "^2.9.1",
+ "pg-pool": "^3.10.1",
+ "pg-protocol": "^1.10.3",
+ "pg-types": "2.2.0",
+ "pgpass": "1.0.5"
+ },
+ "engines": {
+ "node": ">= 16.0.0"
+ },
+ "optionalDependencies": {
+ "pg-cloudflare": "^1.2.7"
+ },
+ "peerDependencies": {
+ "pg-native": ">=3.0.1"
+ },
+ "peerDependenciesMeta": {
+ "pg-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/pg-cloudflare": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
+ "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/pg-connection-string": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
+ "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
+ "license": "MIT"
+ },
+ "node_modules/pg-int8": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
+ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/pg-pool": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
+ "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "pg": ">=8.0"
+ }
+ },
+ "node_modules/pg-protocol": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
+ "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
+ "license": "MIT"
+ },
+ "node_modules/pg-types": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
+ "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "license": "MIT",
+ "dependencies": {
+ "pg-int8": "1.0.1",
+ "postgres-array": "~2.0.0",
+ "postgres-bytea": "~1.0.0",
+ "postgres-date": "~1.0.4",
+ "postgres-interval": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pgpass": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
+ "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
+ "license": "MIT",
+ "dependencies": {
+ "split2": "^4.1.0"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/portfinder": {
+ "version": "1.0.37",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz",
+ "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==",
+ "license": "MIT",
+ "dependencies": {
+ "async": "^3.2.6",
+ "debug": "^4.3.6"
+ },
+ "engines": {
+ "node": ">= 10.12"
+ }
+ },
+ "node_modules/postgres-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postgres-bytea": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
+ "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-date": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/postgres-interval": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
+ "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
+ "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.6.3",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/redis": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
+ "integrity": "sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ==",
+ "license": "MIT",
+ "workspaces": [
+ "./packages/*"
+ ],
+ "dependencies": {
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.6.1",
+ "@redis/graph": "1.1.1",
+ "@redis/json": "1.0.7",
+ "@redis/search": "1.2.0",
+ "@redis/time-series": "1.1.0"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-stable-stringify": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/secure-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
+ "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/serverless-http": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/serverless-http/-/serverless-http-3.2.0.tgz",
+ "integrity": "sha512-QvSyZXljRLIGqwcJ4xsKJXwkZnAVkse1OajepxfjkBXV0BMvRS5R546Z4kCBI8IygDzkQY0foNPC/rnipaE9pQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sift": {
+ "version": "17.1.3",
+ "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz",
+ "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==",
+ "license": "MIT"
+ },
+ "node_modules/socket.io": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
+ "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "base64id": "~2.0.0",
+ "cors": "~2.8.5",
+ "debug": "~4.3.2",
+ "engine.io": "~6.6.0",
+ "socket.io-adapter": "~2.5.2",
+ "socket.io-parser": "~4.2.4"
+ },
+ "engines": {
+ "node": ">=10.2.0"
+ }
+ },
+ "node_modules/socket.io-adapter": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
+ "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "~4.3.4",
+ "ws": "~8.17.1"
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-adapter/node_modules/ws": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io-parser": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+ "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+ "license": "MIT",
+ "dependencies": {
+ "@socket.io/component-emitter": "~3.1.0",
+ "debug": "~4.3.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/socket.io-parser/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/socket.io/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/stopwords-iso": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stopwords-iso/-/stopwords-iso-1.1.0.tgz",
+ "integrity": "sha512-I6GPS/E0zyieHehMRPQcqkiBMJKGgLta+1hREixhoLPqEA0AlVFiC43dl8uPpmkkeRdDMzYRWFWk5/l9x7nmNg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/streamsearch": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+ "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+ "license": "MIT"
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/suffix-thumb": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/suffix-thumb/-/suffix-thumb-5.0.2.tgz",
+ "integrity": "sha512-I5PWXAFKx3FYnI9a+dQMWNqTxoRt6vdBdb0O+BJ1sxXCWtSoQCusc13E58f+9p4MYx/qCnEMkD5jac6K2j3dgA==",
+ "license": "MIT"
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/sylvester": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/sylvester/-/sylvester-0.0.12.tgz",
+ "integrity": "sha512-SzRP5LQ6Ts2G5NyAa/jg16s8e3R7rfdFjizy1zeoecYWw+nGL+YA1xZvW/+iJmidBGSdLkuvdwTYEyJEb+EiUw==",
+ "engines": {
+ "node": ">=0.2.6"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz",
+ "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==",
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node-dev": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz",
+ "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.1",
+ "dynamic-dedupe": "^0.3.0",
+ "minimist": "^1.2.6",
+ "mkdirp": "^1.0.4",
+ "resolve": "^1.0.0",
+ "rimraf": "^2.6.1",
+ "source-map-support": "^0.5.12",
+ "tree-kill": "^1.2.2",
+ "ts-node": "^10.4.0",
+ "tsconfig": "^7.0.0"
+ },
+ "bin": {
+ "ts-node-dev": "lib/bin.js",
+ "tsnd": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "*",
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node-dev/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tsconfig": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
+ "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/strip-bom": "^3.0.0",
+ "@types/strip-json-comments": "0.0.30",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "^2.0.0"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
+ "license": "MIT"
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/underscore": {
+ "version": "1.13.7",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz",
+ "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==",
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "license": "MIT"
+ },
+ "node_modules/union": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
+ "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
+ "dependencies": {
+ "qs": "^6.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+ "license": "MIT"
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/uuid": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
+ "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz",
+ "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^5.1.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/wordnet-db": {
+ "version": "3.1.14",
+ "resolved": "https://registry.npmjs.org/wordnet-db/-/wordnet-db-3.1.14.tgz",
+ "integrity": "sha512-zVyFsvE+mq9MCmwXUWHIcpfbrHHClZWZiVOzKSxNJruIcFn2RbY55zkhiAMMxM8zCVSmtNiViq8FsAZSFpMYag==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/wordpos": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/wordpos/-/wordpos-1.2.0.tgz",
+ "integrity": "sha512-3C0pdLnYIV962dyPEmi+QNJhI+RRz2lLY1QiCycUt2qhL8Dalv1huAngfePDmNJ1WHdSAT/fjbDqtbu1KfguCw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^2.0.0",
+ "underscore": ">=1.3.1",
+ "wordnet-db": "^3.1.6"
+ },
+ "bin": {
+ "wordpos": "bin/wordpos-cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "8.18.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
+ "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.67",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz",
+ "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/zod-to-json-schema": {
+ "version": "3.24.6",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz",
+ "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==",
+ "license": "ISC",
+ "peerDependencies": {
+ "zod": "^3.24.1"
+ }
+ }
+ }
+}
diff --git a/team-bhavitha-dsarecommender/server/package.json b/team-bhavitha-dsarecommender/server/package.json
new file mode 100644
index 000000000..2e33609fa
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "server",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "start": "node dist/app.js",
+ "dev": "ts-node-dev --respawn --transpile-only src/app.ts",
+ "build": "tsc",
+ "postbuild": "cp -r src/data dist/data",
+ "test": "jest",
+ "watch": "tsc -w"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "type": "commonjs",
+ "dependencies": {
+ "@google/genai": "^1.7.0",
+ "@google/generative-ai": "^0.24.1",
+ "axios": "^1.10.0",
+ "bcrypt": "^6.0.0",
+ "bcryptjs": "^3.0.2",
+ "compromise": "^14.14.4",
+ "compromise-sentences": "^0.3.0",
+ "cors": "^2.8.5",
+ "dotenv": "^16.5.0",
+ "express": "^5.1.0",
+ "gridfs-stream": "^1.1.1",
+ "jsonwebtoken": "^9.0.2",
+ "mongoose": "^8.16.0",
+ "multer": "^1.4.4",
+ "multer-gridfs-storage": "^5.0.2",
+ "natural": "^8.1.0",
+ "node-summarizer": "^1.0.7",
+ "openai": "^5.3.0",
+ "pdf-parse": "^1.1.1",
+ "serverless-http": "^3.2.0",
+ "socket.io": "^4.8.1"
+ },
+ "devDependencies": {
+ "@types/axios": "^0.9.36",
+ "@types/bcryptjs": "^2.4.6",
+ "@types/body-parser": "^1.19.6",
+ "@types/cors": "^2.8.19",
+ "@types/express": "^5.0.3",
+ "@types/jsonwebtoken": "^9.0.10",
+ "@types/mongoose": "^5.11.96",
+ "@types/node": "^24.0.10",
+ "@types/pdf-parse": "^1.1.5",
+ "ts-node-dev": "^2.0.0",
+ "typescript": "^5.8.3"
+ }
+}
diff --git a/team-bhavitha-dsarecommender/server/recommendation_engine.py b/team-bhavitha-dsarecommender/server/recommendation_engine.py
new file mode 100644
index 000000000..4f00210bc
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/recommendation_engine.py
@@ -0,0 +1,60 @@
+import json
+import networkx as nx
+import os
+
+GRAPH_FILE = 'concept_graph_full.json'
+LEARNER_FILE = 'learner_profiles.json'
+OUTPUT_DIR = 'graph/recommendations/'
+TARGET_CONCEPT = 'Computation' # Example target
+
+# Load graph
+with open(GRAPH_FILE) as f:
+ graph_data = json.load(f)
+G = nx.DiGraph()
+for link in graph_data['links']:
+ G.add_edge(link['source'], link['target'])
+
+# Load learners
+with open(LEARNER_FILE) as f:
+ learners = json.load(f)
+
+os.makedirs(OUTPUT_DIR, exist_ok=True)
+
+def recommend_for_learner(profile):
+ mastered = set(profile['mastered_concepts'])
+ recommendations = []
+ for node in G.nodes:
+ if node in mastered:
+ continue
+ prereqs = list(G.predecessors(node))
+ if all(p in mastered for p in prereqs):
+ recommendations.append(node)
+ return recommendations
+
+def recommend_path(profile, target_concept):
+ mastered = set(profile['mastered_concepts'])
+ min_path = None
+ min_length = float('inf')
+ for start in mastered:
+ if nx.has_path(G, start, target_concept):
+ try:
+ path = nx.dijkstra_path(G, start, target_concept)
+ if len(path) < min_length:
+ min_path = path
+ min_length = len(path)
+ except nx.NetworkXNoPath:
+ continue
+ return min_path if min_path else []
+
+# Generate recommendations
+for learner in learners:
+ rid = learner['learner_id']
+ recs = recommend_for_learner(learner)
+ path = recommend_path(learner, TARGET_CONCEPT)
+ with open(f"{OUTPUT_DIR}recommendations_{rid}.json", "w") as f:
+ json.dump({
+ "learner_id": rid,
+ "recommended_concepts": recs,
+ "path_to_target": path
+ }, f, indent=2)
+ print(f"[β] {rid}: {recs} | Path: {path}")
diff --git a/team-bhavitha-dsarecommender/server/src/app.ts b/team-bhavitha-dsarecommender/server/src/app.ts
new file mode 100644
index 000000000..951a7e3ef
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/app.ts
@@ -0,0 +1,63 @@
+// src/app.ts
+
+import express from "express";
+import bodyParser from "body-parser";
+import learningPathRoutes from "./routes/learningPath";
+import cors from 'cors';
+import authRoutes from './routes/auth';
+import quizRoutes from "./routes/quiz";
+import quizSubmitRoutes from "./routes/quizSubmit";
+import dotenv from "dotenv";
+import connectDB from "./config/db";
+import quizHistoryRoutes from "./routes/quizHistory";
+import recommendationRoutes from "./routes/recommendation";
+import exploreRoutes from "./routes/explore";
+import discussionRoutes from "./routes/discuss";
+import questionRoutes from "./routes/question";
+import reportRoutes from "./routes/report";
+import educatorRoutes from "./routes/educator";
+import Dhruv from "./routes/Dhruv";
+import assignmentRoutes from "./routes/assignment";
+import path from "path";
+
+//dotenv.config({ path: path.join(__dirname, "../../.env") });
+dotenv.config();
+
+const app = express();
+const PORT = 5000;
+app.use(bodyParser.json());
+
+app.use(
+ cors({
+ origin: [
+ "http://localhost:5173", // for local dev
+ "https://cps2-rust.vercel.app", // your deployed frontend
+ ],
+ credentials: true,
+ })
+);
+
+
+app.use("/api/explore", exploreRoutes);
+app.use("/api", learningPathRoutes);
+//app.use('/api', authRoutes);
+//app.use("/api/quiz", quizRoutes);
+app.use("/api", Dhruv);
+app.use("/api/quiz-history", quizHistoryRoutes);
+app.use("/api/recommendation", recommendationRoutes);
+app.use("/api", quizSubmitRoutes);
+app.use("/api", quizRoutes);
+app.use("/api", quizSubmitRoutes);
+app.use("/api", authRoutes);
+app.use("/api/discuss", discussionRoutes);
+app.use("/api/questions", questionRoutes);
+app.use("/api/reports", reportRoutes);
+app.use("/api", educatorRoutes);
+app.use("/api/assignments", assignmentRoutes);
+app.use("/uploads", express.static(path.join(__dirname, "uploads")));
+
+connectDB(); // before app.listen
+app.listen(PORT, () => {
+ console.log(`Server running on http://localhost:${PORT}`);
+});
+
diff --git a/team-bhavitha-dsarecommender/server/src/config/db.ts b/team-bhavitha-dsarecommender/server/src/config/db.ts
new file mode 100644
index 000000000..40054f324
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/config/db.ts
@@ -0,0 +1,237 @@
+// import mongoose from "mongoose";
+
+// const connectDB = async () => {
+// const uri = process.env.MONGO_URI;
+
+// if (!uri) {
+// console.error("β MONGO_URI not found in .env");
+// process.exit(1);
+// }
+
+// try {
+// await mongoose.connect(uri, {
+// useNewUrlParser: true,
+// useUnifiedTopology: true,
+// } as mongoose.ConnectOptions);
+
+// console.log("β
Connected to MongoDB Atlas");
+// } catch (err) {
+// console.error("β MongoDB connection error:", err);
+// process.exit(1);
+// }
+// };
+
+// export default connectDB;
+// // import mongoose from "mongoose";
+
+// // const connectDB = async () => {
+// // const uri = process.env.MONGO_URI;
+
+// // if (!uri) {
+// // console.error("β MONGO_URI not found in .env");
+// // process.exit(1);
+// // }
+
+// // try {
+// // await mongoose.connect(uri, {
+// // useNewUrlParser: true,
+// // useUnifiedTopology: true,
+// // } as mongoose.ConnectOptions);
+
+// // console.log("β
Connected to MongoDB Atlas");
+// // } catch (err) {
+// // console.error("β MongoDB connection error:", err);
+// // process.exit(1);
+// // }
+// // };
+
+// // export default connectDB;
+
+// // import mongoose from "mongoose";
+
+// // const uri = process.env.MONGO_URI;
+
+// // if (!uri) {
+// // throw new Error("β MONGO_URI environment variable not defined");
+// // }
+
+// // // Serverless connection caching
+// // declare global {
+// // var mongooseCache: {
+// // conn: typeof mongoose | null;
+// // promise: Promise | null;
+// // };
+// // }
+
+// // const mongooseCache = global.mongooseCache || { conn: null, promise: null };
+
+// // const connectDB = async () => {
+// // // Return cached connection if available
+// // if (mongooseCache.conn) {
+// // return mongooseCache.conn;
+// // }
+
+// // // Create new connection promise if none exists
+// // if (!mongooseCache.promise) {
+// // mongooseCache.promise = mongoose.connect(uri, {
+// // bufferCommands: false, // Disable Mongoose buffering
+// // serverSelectionTimeoutMS: 5000, // Faster failure in serverless
+// // socketTimeoutMS: 45000, // Close sockets after 45s inactivity
+// // maxIdleTimeMS: 30000, // Close connections after 30s inactivity
+// // } as mongoose.ConnectOptions).then(mongoose => {
+// // console.log("β
Connected to MongoDB Atlas");
+// // return mongoose;
+// // });
+// // }
+
+// // try {
+// // // Cache connection after successful resolution
+// // mongooseCache.conn = await mongooseCache.promise;
+// // } catch (err) {
+// // // Reset promise on failure to allow retries
+// // mongooseCache.promise = null;
+// // console.error("β MongoDB connection error:", err);
+// // throw new Error("Database connection failed");
+// // }
+
+// // // Cache in global object for serverless reuse
+// // if (process.env.NODE_ENV !== "production") {
+// // global.mongooseCache = mongooseCache;
+// // }
+
+// // return mongooseCache.conn;
+// // };
+
+// // export default connectDB;
+
+// import mongoose from "mongoose";
+
+// import dotenv from "dotenv";
+
+// dotenv.config(); // β
load .env file
+// // Serverless connection caching
+// declare global {
+// var mongooseCache: {
+// conn: typeof mongoose | null;
+// promise: Promise | null;
+// };
+// }
+
+// const mongooseCache = global.mongooseCache || { conn: null, promise: null };
+
+// const connectDB = async () => {
+// // Move environment variable check inside function
+// const uri = "mongodb+srv://akssrf2025:Aks1234@cluster0.vg4zbcx.mongodb.net/LearnFlowDB?retryWrites=true&w=majority&appName=Cluster0";
+// if (!uri) {
+// throw new Error("β MONGO_URI environment variable not defined");
+// }
+
+// // Return cached connection if available
+// if (mongooseCache.conn) {
+// return mongooseCache.conn;
+// }
+
+// // Create new connection promise if none exists
+// if (!mongooseCache.promise) {
+// mongooseCache.promise = mongoose.connect(uri, {
+// bufferCommands: false,
+// serverSelectionTimeoutMS: 5000,
+// socketTimeoutMS: 45000,
+// maxIdleTimeMS: 30000,
+// } as mongoose.ConnectOptions).then(mongoose => {
+// console.log("β
Connected to MongoDB Atlas");
+// return mongoose;
+// }).catch(err => {
+// console.error("β MongoDB connection error:", err);
+// mongooseCache.promise = null; // Reset on failure
+// throw err;
+// });
+// }
+
+// try {
+// // Cache connection after successful resolution
+// mongooseCache.conn = await mongooseCache.promise;
+// } catch (err) {
+// // This catch block might be redundant now
+// mongooseCache.promise = null;
+// throw new Error("Database connection failed");
+// }
+
+// // Cache in global object for serverless reuse
+// if (process.env.NODE_ENV !== "production") {
+// global.mongooseCache = mongooseCache;
+// }
+
+// return mongooseCache.conn;
+// };
+
+// export default connectDB;
+
+import mongoose from "mongoose";
+declare global {
+ var mongooseCache: {
+ conn: typeof mongoose | null;
+ promise: Promise | null;
+ };
+}
+
+// Initialize
+global.mongooseCache = global.mongooseCache || { conn: null, promise: null };
+
+const connectDB = async () => {
+ const uri = process.env.MONGO_URI;
+
+ if (!uri) {
+ throw new Error("β MONGO_URI environment variable not defined");
+ }
+
+ // Check connection health before returning
+ if (global.mongooseCache.conn && global.mongooseCache.conn.connection.readyState === 1) {
+ return global.mongooseCache.conn;
+ }
+
+ // Create new connection if none exists or previous failed
+ if (!global.mongooseCache.promise) {
+ global.mongooseCache.promise = mongoose.connect(uri, {
+ bufferCommands: false,
+ serverSelectionTimeoutMS: 3000, // Reduced from 5s
+ socketTimeoutMS: 30000, // Reduced from 45s
+ maxIdleTimeMS: 10000, // Reduced from 30s
+ waitQueueTimeoutMS: 3000,
+ heartbeatFrequencyMS: 5000,
+ } as mongoose.ConnectOptions)
+ .then(mongoose => {
+ console.log("β
Connected to MongoDB Atlas");
+ return mongoose;
+ })
+ .catch(err => {
+ console.error("β MongoDB connection error:", err);
+ global.mongooseCache.promise = null;
+ throw err;
+ });
+ }
+
+ try {
+ global.mongooseCache.conn = await global.mongooseCache.promise;
+ } catch (err) {
+ global.mongooseCache.promise = null;
+ throw new Error("Database connection failed");
+ }
+
+ return global.mongooseCache.conn;
+};
+
+//connection event listeners
+mongoose.connection.on('connected', () =>
+ console.log(`Mongoose connected to ${mongoose.connection.db?.databaseName}`)
+);
+
+mongoose.connection.on('disconnected', () =>
+ console.warn('Mongoose disconnected!')
+);
+
+mongoose.connection.on('error', (err) =>
+ console.error('Mongoose connection error:', err)
+);
+
+export default connectDB;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/data/chunks.json b/team-bhavitha-dsarecommender/server/src/data/chunks.json
new file mode 100644
index 000000000..91d243b15
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/data/chunks.json
@@ -0,0 +1,146 @@
+[
+ {
+ "topic": "Computation",
+ "content": "This topic appears in lecture: \"What is computation?\"."
+ },
+ {
+ "topic": "Algorithms",
+ "content": "This topic appears in lecture: \"What is computation?\"."
+ },
+ {
+ "topic": "Problem Solving",
+ "content": "This topic appears in lecture: \"What is computation?\"."
+ },
+ {
+ "topic": "Conditionals",
+ "content": "This topic appears in lecture: \"Branching and Iteration\"."
+ },
+ {
+ "topic": "Loops",
+ "content": "This topic appears in lecture: \"Branching and Iteration\"."
+ },
+ {
+ "topic": "Control Flow",
+ "content": "This topic appears in lecture: \"Branching and Iteration\"."
+ },
+ {
+ "topic": "String Manipulation",
+ "content": "This topic appears in lecture: \"String Manipulation, Guess and Check, Approximations, Bisection\"."
+ },
+ {
+ "topic": "Guess and Check",
+ "content": "This topic appears in lecture: \"String Manipulation, Guess and Check, Approximations, Bisection\"."
+ },
+ {
+ "topic": "Approximation",
+ "content": "This topic appears in lecture: \"String Manipulation, Guess and Check, Approximations, Bisection\"."
+ },
+ {
+ "topic": "Bisection Search",
+ "content": "This topic appears in lecture: \"String Manipulation, Guess and Check, Approximations, Bisection\"."
+ },
+ {
+ "topic": "Decomposition",
+ "content": "This topic appears in lecture: \"Decomposition, Abstractions, Functions\"."
+ },
+ {
+ "topic": "Abstraction",
+ "content": "This topic appears in lecture: \"Decomposition, Abstractions, Functions\"."
+ },
+ {
+ "topic": "Functions",
+ "content": "This topic appears in lecture: \"Decomposition, Abstractions, Functions\"."
+ },
+ {
+ "topic": "Tuples",
+ "content": "This topic appears in lecture: \"Tuples, Lists, Aliasing, Mutability, Cloning\"."
+ },
+ {
+ "topic": "Lists",
+ "content": "This topic appears in lecture: \"Tuples, Lists, Aliasing, Mutability, Cloning\"."
+ },
+ {
+ "topic": "Aliasing",
+ "content": "This topic appears in lecture: \"Tuples, Lists, Aliasing, Mutability, Cloning\"."
+ },
+ {
+ "topic": "Mutability",
+ "content": "This topic appears in lecture: \"Tuples, Lists, Aliasing, Mutability, Cloning\"."
+ },
+ {
+ "topic": "Cloning",
+ "content": "This topic appears in lecture: \"Tuples, Lists, Aliasing, Mutability, Cloning\"."
+ },
+ {
+ "topic": "Recursion",
+ "content": "This topic appears in lecture: \"Recursion, Dictionaries\"."
+ },
+ {
+ "topic": "Dictionaries",
+ "content": "This topic appears in lecture: \"Recursion, Dictionaries\"."
+ },
+ {
+ "topic": "Testing",
+ "content": "This topic appears in lecture: \"Testing, Debugging, Exceptions, Assertions\"."
+ },
+ {
+ "topic": "Debugging",
+ "content": "This topic appears in lecture: \"Testing, Debugging, Exceptions, Assertions\"."
+ },
+ {
+ "topic": "Exceptions",
+ "content": "This topic appears in lecture: \"Testing, Debugging, Exceptions, Assertions\"."
+ },
+ {
+ "topic": "Assertions",
+ "content": "This topic appears in lecture: \"Testing, Debugging, Exceptions, Assertions\"."
+ },
+ {
+ "topic": "Classes",
+ "content": "This topic appears in lecture: \"Object Oriented Programming\"."
+ },
+ {
+ "topic": "OOP",
+ "content": "This topic appears in lecture: \"Object Oriented Programming\"."
+ },
+ {
+ "topic": "Encapsulation",
+ "content": "This topic appears in lecture: \"Object Oriented Programming\"."
+ },
+ {
+ "topic": "Inheritance",
+ "content": "This topic appears in lecture: \"Python Classes and Inheritance\"."
+ },
+ {
+ "topic": "Subclasses",
+ "content": "This topic appears in lecture: \"Python Classes and Inheritance\"."
+ },
+ {
+ "topic": "Class Hierarchies",
+ "content": "This topic appears in lecture: \"Python Classes and Inheritance\"."
+ },
+ {
+ "topic": "Big-O Notation",
+ "content": "This topic appears in lecture: \"Understanding Program Efficiency, Part 1\"."
+ },
+ {
+ "topic": "Efficiency",
+ "content": "This topic appears in lecture: \"Understanding Program Efficiency, Part 1\"."
+ },
+ {
+ "topic": "Efficiency",
+ "content": "This topic appears in lecture: \"Understanding Program Efficiency, Part 2\"."
+ },
+ {
+ "topic": "Space Complexity",
+ "content": "This topic appears in lecture: \"Understanding Program Efficiency, Part 2\"."
+ },
+ {
+ "topic": "Search Algorithms",
+ "content": "This topic appears in lecture: \"Searching and Sorting\"."
+ },
+ {
+ "topic": "Sorting Algorithms",
+ "content": "This topic appears in lecture: \"Searching and Sorting\"."
+ }
+]
\ No newline at end of file
diff --git a/server/src/data/concept_graph_full.json b/team-bhavitha-dsarecommender/server/src/data/concept_graph_full.json
similarity index 98%
rename from server/src/data/concept_graph_full.json
rename to team-bhavitha-dsarecommender/server/src/data/concept_graph_full.json
index 359b1c7b3..474af4996 100644
--- a/server/src/data/concept_graph_full.json
+++ b/team-bhavitha-dsarecommender/server/src/data/concept_graph_full.json
@@ -107,6 +107,9 @@
},
{
"id": "Sorting Algorithms"
+ },
+ {
+ "id": "Complexity Analysis"
}
],
"links": [
@@ -316,7 +319,7 @@
},
{
"source": "Efficiency",
- "target": "Efficiency"
+ "target": "Complexity Analysis"
},
{
"source": "Efficiency",
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture1.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture1.pdf
new file mode 100644
index 000000000..a5a794ae5
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture1.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture10.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture10.pdf
new file mode 100644
index 000000000..f3581a671
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture10.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture11.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture11.pdf
new file mode 100644
index 000000000..a128442ea
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture11.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture12.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture12.pdf
new file mode 100644
index 000000000..0671ffc28
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture12.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture2.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture2.pdf
new file mode 100644
index 000000000..19c4f8045
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture2.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture3.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture3.pdf
new file mode 100644
index 000000000..e8a1d0dca
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture3.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture4.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture4.pdf
new file mode 100644
index 000000000..ecb09318d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture4.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture5.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture5.pdf
new file mode 100644
index 000000000..632b81937
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture5.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture6.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture6.pdf
new file mode 100644
index 000000000..99ff9cc40
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture6.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture7.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture7.pdf
new file mode 100644
index 000000000..be4a27d5c
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture7.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture8.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture8.pdf
new file mode 100644
index 000000000..ad17db03f
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture8.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/data/lecture9.pdf b/team-bhavitha-dsarecommender/server/src/data/lecture9.pdf
new file mode 100644
index 000000000..01e519b2d
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/data/lecture9.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/middleware/auth.ts b/team-bhavitha-dsarecommender/server/src/middleware/auth.ts
new file mode 100644
index 000000000..351ffc704
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/middleware/auth.ts
@@ -0,0 +1,35 @@
+// src/middleware/auth.ts
+import { Request, Response, NextFunction } from "express";
+import jwt from "jsonwebtoken";
+
+const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";
+
+declare module "express" {
+ interface Request {
+ user?: { username: string; role: string };
+ }
+}
+
+export default function authenticate(
+ req: Request,
+ res: Response,
+ next: NextFunction
+): void {
+ const token = req.headers.authorization?.split(" ")[1];
+
+ if (!token) {
+ res.status(401).json({ error: "Authentication required" });
+ return;
+ }
+
+ try {
+ const decoded = jwt.verify(token, JWT_SECRET) as {
+ username: string;
+ role: string;
+ };
+ req.user = decoded;
+ next();
+ } catch (err) {
+ res.status(403).json({ error: "Invalid token" });
+ }
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/middleware/authorize.ts b/team-bhavitha-dsarecommender/server/src/middleware/authorize.ts
new file mode 100644
index 000000000..9e4bef7de
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/middleware/authorize.ts
@@ -0,0 +1,18 @@
+// src/middleware/authorize.ts
+import { Request, Response, NextFunction } from "express";
+
+export default function authorize(role: string) {
+ return (req: Request, res: Response, next: NextFunction): void => {
+ if (!req.user) {
+ res.status(401).json({ error: "Authentication required" });
+ return;
+ }
+
+ if (req.user.role !== role && req.user.role !== "admin") {
+ res.status(403).json({ error: "Insufficient permissions" });
+ return;
+ }
+
+ next();
+ };
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/middleware/sessionAuth.ts b/team-bhavitha-dsarecommender/server/src/middleware/sessionAuth.ts
new file mode 100644
index 000000000..589c2748f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/middleware/sessionAuth.ts
@@ -0,0 +1,9 @@
+// // server/src/middleware/sessionAuth.ts
+// import { Request, Response, NextFunction } from "express";
+// module.exports = (req:Request, res:Response, next) => {
+// if (!req.session.user) {
+// return res.status(401).json({ error: "Authentication required" });
+// }
+// req.user = req.session.user;
+// next();
+// };
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/models/AskedQuestion.ts b/team-bhavitha-dsarecommender/server/src/models/AskedQuestion.ts
new file mode 100644
index 000000000..431b202f1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/AskedQuestion.ts
@@ -0,0 +1,13 @@
+import mongoose from "mongoose";
+
+const AskedQuestionSchema = new mongoose.Schema({
+ topic: String,
+ questionIndex: Number,
+ questionText: String,
+ askedBy: String,
+ response: String,
+ isAnswered: { type: Boolean, default: false },
+ createdAt: { type: Date, default: Date.now },
+});
+
+export default mongoose.model("AskedQuestion", AskedQuestionSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/EducatorId.ts b/team-bhavitha-dsarecommender/server/src/models/EducatorId.ts
new file mode 100644
index 000000000..44f075136
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/EducatorId.ts
@@ -0,0 +1,17 @@
+// models/EducatorID.ts
+import mongoose from "mongoose";
+
+const EducatorIDSchema = new mongoose.Schema({
+ eid: {
+ type: String,
+ required: true,
+ unique: true,
+ length: 16,
+ },
+ used: {
+ type: Boolean,
+ default: false,
+ },
+});
+
+export default mongoose.model("EducatorID", EducatorIDSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/PlaySession.ts b/team-bhavitha-dsarecommender/server/src/models/PlaySession.ts
new file mode 100644
index 000000000..eb2d32a4b
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/PlaySession.ts
@@ -0,0 +1,28 @@
+// models/PlaySession.ts
+import mongoose from "mongoose";
+
+const sessionSchema = new mongoose.Schema({
+ userId: String,
+ targetConcept: String,
+ prerequisites: [String],
+ weakConcepts: [String],
+ answeredQuestions: [
+ {
+ concept: String,
+ question: String,
+ answer: String,
+ },
+ ],
+ questionQueue: [
+ {
+ concept: String,
+ question: String,
+ },
+ ],
+ currentIndex: {
+ type: Number,
+ default: 0,
+ },
+}, { timestamps: true });
+
+export default mongoose.model("PlaySession", sessionSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/QuestionReport.ts b/team-bhavitha-dsarecommender/server/src/models/QuestionReport.ts
new file mode 100644
index 000000000..156090dd3
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/QuestionReport.ts
@@ -0,0 +1,13 @@
+import mongoose from "mongoose";
+
+const QuestionReportSchema = new mongoose.Schema({
+ topic: String,
+ questionIndex: Number,
+ questionText: String,
+ reportedBy: String,
+ reason: String,
+ status: { type: String, default: "Pending" },
+ createdAt: { type: Date, default: Date.now },
+});
+
+export default mongoose.model("QuestionReport", QuestionReportSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/QuizResult.ts b/team-bhavitha-dsarecommender/server/src/models/QuizResult.ts
new file mode 100644
index 000000000..89a0e902c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/QuizResult.ts
@@ -0,0 +1,13 @@
+import mongoose from "mongoose";
+
+const quizResultSchema = new mongoose.Schema({
+ username: { type: String, required: true },
+ topic: { type: String, required: true },
+ score: { type: Number, required: true },
+ mastery: { type: Number, required: true },
+ answers: [String],
+ correctAnswers: [String],
+ createdAt: { type: Date, default: Date.now }
+});
+
+export default mongoose.model("QuizResult", quizResultSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/assignment.ts b/team-bhavitha-dsarecommender/server/src/models/assignment.ts
new file mode 100644
index 000000000..a285b3a6b
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/assignment.ts
@@ -0,0 +1,13 @@
+import mongoose from "mongoose";
+
+const assignmentSchema = new mongoose.Schema(
+ {
+ username: { type: String, required: true },
+ title: { type: String, required: true },
+ description: { type: String },
+ fileUrl: { type: String, required: true },
+ },
+ { timestamps: true }
+);
+
+export const Assignment = mongoose.model("Assignment", assignmentSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/concepts.ts b/team-bhavitha-dsarecommender/server/src/models/concepts.ts
new file mode 100644
index 000000000..da7a8f018
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/concepts.ts
@@ -0,0 +1,53 @@
+// import mongoose from "mongoose";
+
+// const conceptSchema = new mongoose.Schema({
+// name: String,
+// description: String,
+// spotlight_fact: String,
+// lecture: String,
+// });
+
+// export default mongoose.model("Concept", conceptSchema);
+// import mongoose from "mongoose";
+
+// const conceptSchema = new mongoose.Schema({
+// name: String,
+// description: String,
+// spotlight_fact: String,
+// lecture: String,
+// examples: [String],
+// related_topics: [String],
+// quiz_available: Boolean,
+// });
+
+// export default mongoose.model("Concept", conceptSchema);
+
+import mongoose from "mongoose";
+
+const conceptSchema = new mongoose.Schema({
+ name: { type: String, required: true, unique: true },
+ description: String,
+ spotlight_fact: String,
+ lecture: String,
+ examples: [String],
+ related_topics: [String],
+ quiz_available: Boolean,
+
+ // Structured Notes Fields
+ structuredNotes: {
+ overview: String,
+ keyConcepts: [
+ {
+ name: String,
+ explanation: String,
+ },
+ ],
+ frequentlyUsed: [String],
+ commonPitfalls: [String],
+ bestPractices: [String],
+ latestReferences: [String],
+ },
+});
+
+export default mongoose.model("Concept", conceptSchema);
+
diff --git a/team-bhavitha-dsarecommender/server/src/models/discussion.ts b/team-bhavitha-dsarecommender/server/src/models/discussion.ts
new file mode 100644
index 000000000..8b0adc8d6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/discussion.ts
@@ -0,0 +1,39 @@
+import mongoose from "mongoose";
+
+const replySchema = new mongoose.Schema(
+ {
+ username: { type: String, required: true },
+ text: { type: String, required: true },
+ role: { type: String, enum: ["student", "educator"], default: "student" },
+ createdAt: { type: Date, default: Date.now },
+ },
+ { _id: true }
+);
+
+const commentSchema = new mongoose.Schema(
+ {
+ username: { type: String, required: true },
+ text: { type: String, required: true },
+ role : { type: String, enum: ["student", "educator"], default: "student" },
+ createdAt: { type: Date, default: Date.now },
+ replies: [replySchema],
+ },
+ { _id: true }
+);
+
+const discussionThreadSchema = new mongoose.Schema(
+ {
+ topic: { type: String },
+ createdBy: { type: String, required: true }, // or { type: mongoose.Schema.Types.ObjectId, ref: 'User' } for population
+ questionIndex: { type: Number },
+ questionText: { type: String },
+ isGeneral: { type: Boolean, default: false },
+ comments: [commentSchema],
+ },
+ { timestamps: true }
+);
+
+// Optional: add a compound index for question-based threads
+discussionThreadSchema.index({ topic: 1, questionIndex: 1 }, { unique: true, sparse: true });
+
+export default mongoose.model("Discussion", discussionThreadSchema);
diff --git a/team-bhavitha-dsarecommender/server/src/models/users.ts b/team-bhavitha-dsarecommender/server/src/models/users.ts
new file mode 100644
index 000000000..357305003
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/models/users.ts
@@ -0,0 +1,15 @@
+import mongoose from "mongoose";
+
+const UserSchema = new mongoose.Schema({
+ name: { type: String, required: true },
+ username: { type: String, required: true, unique: true },
+ role: { type: String, enum: ['student', 'educator'], default: 'student' },
+ password: { type: String, required: true },
+ email: { type: String },
+ progress: { type: [String], default: [] },
+ mastery: { type: Object, default: {} },
+ recommendations: { type: [String], default: [] },
+});
+
+const User = mongoose.model("User", UserSchema);
+export default User;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/Dhruv.ts b/team-bhavitha-dsarecommender/server/src/routes/Dhruv.ts
new file mode 100644
index 000000000..889354b3e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/Dhruv.ts
@@ -0,0 +1,129 @@
+import { Router } from "express";
+import PlaySession from "../models/PlaySession";
+import { getAllPrerequisites } from "../utils/conceptGraph";
+import { getBinaryQuestionForTopic } from "../utils/extractContent";
+const router = Router();
+
+// GET /start?concept=Binary Search&userId=123
+router.get("/start", async (req, res) => {
+ const { concept, userId } = req.query as { concept: string; userId: string };
+
+ const prerequisites = getAllPrerequisites(concept);
+
+ // Generate binary questions for all prerequisites
+ const questionQueue: { concept: string; question: string }[] = [];
+
+ for (const pre of prerequisites) {
+ const question = await getBinaryQuestionForTopic(pre);
+ if (question) {
+ questionQueue.push({ concept: pre, question });
+ }
+ }
+
+ const session = await PlaySession.create({
+ userId,
+ targetConcept: concept,
+ prerequisites,
+ questionQueue,
+ answeredQuestions: [],
+ weakConcepts: [],
+ currentIndex: 0,
+ });
+
+ await session.save();
+
+ const firstQuestion = questionQueue[0];
+
+ res.json({
+ sessionId: session._id,
+ question: firstQuestion,
+ isComplete: false,
+ });
+});
+
+
+router.post("/answer", async (req, res) => {
+ try {
+ const { sessionId, answer } = req.body;
+
+ if (!sessionId || !answer) {
+ res.status(400).json({ error: "Missing sessionId or answer" });
+ return;
+ }
+
+ const session = await PlaySession.findById(sessionId);
+ if (!session) {
+ res.status(404).json({ error: "Session not found" });
+ return;
+ }
+
+ const index = session.currentIndex;
+ if (index >= session.questionQueue.length) {
+ res.status(400).json({ error: "Session already completed" });
+ return;
+ }
+
+ const { concept, question } = session.questionQueue[index];
+
+ // Save the answer
+ session.answeredQuestions.push({ concept, question, answer });
+
+ // Track weak concepts
+ if (
+ typeof answer === "string" &&
+ answer.toLowerCase() === "no" &&
+ typeof concept === "string" &&
+ !session.weakConcepts.includes(concept)
+ ) {
+ session.weakConcepts.push(concept);
+ }
+
+ session.currentIndex += 1;
+ await session.save();
+
+ if (session.currentIndex >= session.questionQueue.length) {
+ res.json({
+ isComplete: true,
+ results: {
+ strongConcepts: session.prerequisites.filter((c) => !session.weakConcepts.includes(c)),
+ weakConcepts: session.weakConcepts,
+ recommendedConcepts: session.weakConcepts,
+ },
+ });
+ return;
+ }
+
+ const nextQuestion = session.questionQueue[session.currentIndex];
+
+ res.json({
+ isComplete: false,
+ question: nextQuestion,
+ });
+ return;
+ } catch (error) {
+ console.error("β Error in /api/answer:", error);
+ res.status(500).json({ error: "Internal server error" });
+ return;
+ }
+});
+
+router.get("/user/:id/playground-attempts", async (req, res) => {
+ const { id } = req.params;
+
+ const sessions = await PlaySession.find({ userId: id });
+ const history: Record = {};
+
+ for (const s of sessions) {
+ if (typeof s.targetConcept === "string" && s.targetConcept) {
+ history[s.targetConcept] = {
+ strongConcepts: s.prerequisites.filter((c) => !s.weakConcepts.includes(c)),
+ weakConcepts: s.weakConcepts,
+ recommendedConcepts: s.weakConcepts,
+ };
+ }
+ }
+
+ res.json(history);
+});
+
+ export default router;
\ No newline at end of file
diff --git a/server/src/routes/__tests__/learning-path.http b/team-bhavitha-dsarecommender/server/src/routes/__tests__/learning-path.http
similarity index 100%
rename from server/src/routes/__tests__/learning-path.http
rename to team-bhavitha-dsarecommender/server/src/routes/__tests__/learning-path.http
diff --git a/team-bhavitha-dsarecommender/server/src/routes/__tests__/learningPath.test.ts b/team-bhavitha-dsarecommender/server/src/routes/__tests__/learningPath.test.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/team-bhavitha-dsarecommender/server/src/routes/__tests__/testGemini.ts b/team-bhavitha-dsarecommender/server/src/routes/__tests__/testGemini.ts
new file mode 100644
index 000000000..14304b9fa
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/__tests__/testGemini.ts
@@ -0,0 +1,18 @@
+import axios from 'axios';
+
+const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent";
+const API_KEY = process.env.GEMINI_API_KEY;
+
+async function testGemini() {
+ try {
+ const res = await axios.post(`${GEMINI_API_URL}?key=${API_KEY}`, {
+ contents: [{ parts: [{ text: "Say hello in JSON format." }] }]
+ });
+
+ console.log("β
Gemini Response:", res.data);
+ } catch (err: any) {
+ console.error("β Gemini API Test Failed:", err?.response?.data || err.message);
+ }
+}
+
+testGemini();
diff --git a/team-bhavitha-dsarecommender/server/src/routes/assignment.ts b/team-bhavitha-dsarecommender/server/src/routes/assignment.ts
new file mode 100644
index 000000000..2c74fe226
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/assignment.ts
@@ -0,0 +1,63 @@
+import express from "express";
+import multer from "multer";
+import path from "path";
+import fs from "fs";
+import { Assignment } from "../models/assignment";
+
+const router = express.Router();
+
+// Ensure uploads directory exists
+const uploadPath = path.join(__dirname, "..", "uploads");
+if (!fs.existsSync(uploadPath)) fs.mkdirSync(uploadPath);
+
+// Configure Multer storage
+const storage = multer.diskStorage({
+ destination: function (req, file, cb) {
+ cb(null, uploadPath);
+ },
+ filename: function (req, file, cb) {
+ const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
+ cb(null, uniqueSuffix + "-" + file.originalname);
+ },
+});
+const upload = multer({ storage });
+
+router.post("/", upload.single("file"), async (req, res) => {
+ try {
+ const { username, title, description } = req.body;
+
+ if (!username || !title || !description || !req.file) {
+ res.status(400).json({ error: "Missing required fields" });
+ return;
+ }
+
+ // Absolute file URL using host + protocol
+ const fileUrl = `${req.protocol}://${req.get("host")}/uploads/${req.file.filename}`;
+
+ const assignment = new Assignment({
+ username,
+ title,
+ description,
+ fileUrl,
+ });
+
+ await assignment.save();
+ res.status(201).json({ message: "Assignment created", assignment });
+ } catch (err) {
+ console.error("Error saving assignment:", err);
+ res.status(500).json({ error: "Failed to save assignment" });
+ }
+});
+//Get all assignments for a student
+router.get("/:username", async (req, res) => {
+ const { username } = req.params;
+ try {
+ const assignments = await Assignment.find({ username }).sort({ createdAt: -1 });
+ res.json(assignments);
+ } catch (err) {
+ console.error("Failed to fetch assignments", err);
+ res.status(500).json({ error: "Could not fetch assignments" });
+ }
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/auth.ts b/team-bhavitha-dsarecommender/server/src/routes/auth.ts
new file mode 100644
index 000000000..14027e706
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/auth.ts
@@ -0,0 +1,260 @@
+// import express, { Request, Response } from 'express';
+// const router = express.Router();
+// import User from "../models/users";
+
+// // POST /api/login
+// router.post("/login", async (req, res) => {
+// const { username, password } = req.body;
+
+// if (!username || !password) {
+// res.status(400).json({ error: "Username and password are required." });
+// return;
+// }
+
+// try {
+// const user = await User.findOne({ username });
+
+// if (!user) {
+// res.status(404).json({ error: "User not found." });
+// return;
+// }
+
+// if (user.password !== password) {
+// res.status(401).json({ error: "Invalid credentials." });
+// return;
+// }
+
+// // Send user profile (omit password)
+// const { name, email, progress, mastery, recommendations } = user;
+
+// res.status(200).json({
+// message: "Login successful",
+// user: {
+// username,
+// name,
+// email,
+// progress,
+// mastery,
+// recommendations,
+// },
+// });
+// return;
+// } catch (err) {
+// console.error("Login error:", err);
+// res.status(500).json({ error: "Internal server error." });
+// return;
+// }
+// });
+
+
+// // POST /api/register
+// router.post("/register", async (req, res) => {
+// const { name, username, password, email, progress } = req.body;
+
+// if (!name || !username || !password) {
+// res.status(400).json({ error: "Missing required fields." });
+// return;
+// }
+
+// try {
+// const existingUser = await User.findOne({ username });
+// if (existingUser) {
+// res.status(409).json({ error: "Username already exists." });
+// return;
+// }
+
+// const newUser = new User({
+// name,
+// username,
+// password,
+// email,
+// progress,
+// mastery: {},
+// recommendations: [],
+// });
+
+// await newUser.save();
+
+// res.status(201).json({ message: "User registered.", user: newUser });
+// return;
+// } catch (err) {
+// console.error("Registration error:", err);
+// res.status(500).json({ error: "Internal server error." });
+// return;
+// }
+// });
+// router.get("/test", (req, res) => {
+// res.json({ message: "CORS test working!" });
+// });
+
+// export default router;
+import express, { Request, Response } from 'express';
+const router = express.Router();
+import bcrypt from 'bcryptjs';
+import User from "../models/users";
+import mongoose from 'mongoose';
+import connectDB from '../config/db';
+import EducatorID from "../models/EducatorId";
+
+
+// router.use((req, res, next) => {
+// const allowedOrigins = [
+// 'https://cps2-rust.vercel.app',
+// 'https://localhost:5173'
+// ];
+
+// const origin = req.headers.origin || '';
+// if (allowedOrigins.includes(origin)) {
+// res.setHeader('Access-Control-Allow-Origin', origin);
+// }
+
+// res.setHeader('Access-Control-Allow-Credentials', 'true');
+// res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
+// res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
+
+// if (req.method === 'OPTIONS') {
+// res.sendStatus(200);
+// return;
+// }
+
+// next();
+// });
+router.use(async (req, res, next) => {
+ try {
+ // Establish DB connection
+ const db = await connectDB();
+
+ // Verify connection state
+ if (db.connection.readyState !== 1) {
+ console.error('DB connection not ready. State:', db.connection.readyState);
+ res.status(503).json({ error: "Database is initializing" });
+ return;
+ }
+
+ next();
+ } catch (err) {
+ console.error('Database connection error:', err);
+ res.status(500).json({ error: "Database connection failed" });
+ }
+});
+// POST /api/login
+router.post("/login", async (req: Request, res: Response) => {
+ try {
+ console.log("LOGIN attempt - body:", req.body);
+
+ const { username, password } = req.body;
+
+ if (!username || !password) {
+ console.warn("Missing username or password");
+ res.status(400).json({ error: "Username and password are required." });
+ return;
+ }
+ if (mongoose.connection.readyState !== 1) {
+ console.warn('DB connection not ready during login. State:', mongoose.connection.readyState);
+ res.status(503).json({ error: "Database is initializing. Please retry." });
+ return;
+ }
+ const user = await User.findOne({ username }).select('+password').lean();
+ if (!user) {
+ console.warn("User not found:", username);
+ res.status(404).json({ error: "User not found." });
+ return;
+ }
+
+ const isMatch = await bcrypt.compare(password, user.password);
+ if (!isMatch) {
+ console.warn("Invalid password for:", username);
+ res.status(401).json({ error: "Invalid credentials." });
+ return;
+ }
+
+ const { password: _, ...userData } = user;
+ console.log("Login successful for:", username);
+
+ res.status(200).json({
+ message: "Login successful",
+ user: userData
+ });
+ return;
+ } catch (err) {
+ console.error("Login error:", err);
+ res.status(500).json({ error: "Internal server error." });
+ return;
+ }
+});
+
+
+// POST /api/register
+router.post("/register", async (req: Request, res: Response) => {
+ const { name, username,role, password, email, progress, eid } = req.body;
+
+ if (!name || !username || !password) {
+ res.status(400).json({ error: "Missing required fields." });
+ return;
+ }
+
+
+
+ if (role === "educator") {
+ if (!eid || !/^\d{16}$/.test(eid)) {
+ res.status(400).json({ error: "Invalid Educator ID." });
+ return;
+ }
+
+ // Check if EID exists and is unused
+ const validEid = await EducatorID.findOne({ eid, used: false });
+ if (!validEid) {
+ res.status(403).json({ error: "Educator ID is invalid or already used." });
+ return;
+ }
+ }
+
+ if (mongoose.connection.readyState !== 1) {
+ res.status(503).json({ error: "Database is initializing. Please retry." });
+ return;
+ }
+
+ try {
+ const existingUser = await User.findOne({ username });
+ if (existingUser) {
+ res.status(409).json({ error: "Username already exists." });
+ return;
+ }
+
+ const salt = await bcrypt.genSalt(10);
+ const hashedPassword = await bcrypt.hash(password, salt);
+
+ const newUser = new User({
+ name,
+ username,
+ password: hashedPassword,
+ email: email || undefined,
+ role,
+ progress: progress || {},
+ mastery: {},
+ recommendations: [],
+ });
+
+ await newUser.save();
+
+ if (role === "educator") {
+ await EducatorID.updateOne({ eid }, { $set: { used: true } });
+ }
+
+ const { password: _, ...userData } = newUser.toObject();
+
+
+ res.status(201).json({
+ message: `${role.charAt(0).toUpperCase() + role.slice(1)} registered successfully.`,
+ user: userData,
+ });
+ return;
+ } catch (err) {
+ console.error("Registration error:", err);
+ res.status(500).json({ error: "Internal server error." });
+ }
+ return;
+});
+
+
+export default router;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/routes/discuss.ts b/team-bhavitha-dsarecommender/server/src/routes/discuss.ts
new file mode 100644
index 000000000..f6f62ef38
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/discuss.ts
@@ -0,0 +1,288 @@
+// src/routes/discussionRoutes.ts
+import express from "express";
+import Discussion from "../models/discussion";
+
+const router = express.Router();
+
+// 1. Get all discussion threads
+router.get("/all", async (_, res) => {
+ try {
+ const threads = await Discussion.find().sort({ updatedAt: -1 });
+ res.json({ threads });
+ } catch (err) {
+ console.error("Failed to fetch discussions:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+// 2. General discussion thread (updated field names)
+router.post("/general", async (req, res) => {
+ const { username, text } = req.body;
+
+ if (!username || !text) {
+ res.status(400).json({ error: "Missing username or comment text" });
+ return;
+ }
+
+ try {
+ const thread = new Discussion({
+ isGeneral: true,
+ createdBy: username,
+ comments: [{ username, text }],
+ });
+ await thread.save();
+ res.status(201).json({ message: "General discussion thread created", thread });
+ } catch (err) {
+ console.error("Error creating general discussion:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+
+// 3. Create or get a thread for a specific question
+router.post("/create-or-get", async (req, res) => {
+ const { topic, questionIndex, questionText, username } = req.body;
+
+ if (!topic || questionIndex === undefined || !questionText || !username) {
+ res.status(400).json({ error: "Missing topic, questionIndex, questionText, or username" });
+ return;
+ }
+
+ try {
+ let thread = await Discussion.findOne({ topic, questionIndex });
+ if (!thread) {
+ thread = new Discussion({
+ topic,
+ questionIndex,
+ questionText,
+ createdBy: username,
+ });
+ await thread.save();
+ }
+ res.status(200).json(thread);
+ } catch (err) {
+ console.error("Error in /create-or-get:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+
+// 4. Add comment to question-based thread (updated path and fields)
+router.post("/question/:topic/:qIndex", async (req, res) => {
+ const { topic, qIndex } = req.params;
+ const { username, text } = req.body; // Changed to consistent fields
+
+ if (!username || !text) {
+ res.status(400).json({ error: "Missing username or comment text" });
+ return;
+ }
+
+ try {
+ let thread = await Discussion.findOne({ topic, questionIndex: qIndex });
+ if (!thread) {
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+
+ thread.comments.push({ username, text });
+ await thread.save();
+ res.status(201).json({ message: "Comment added", thread });
+ } catch (err) {
+ console.error("Failed to add comment:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+// 5. Comment on a thread using its ID (updated path)
+router.post("/thread/:id/comment", async (req, res) => {
+ const { id } = req.params;
+ const { username, text , role} = req.body;
+
+ if (!username || !text) {
+ res.status(400).json({ error: "Missing username or comment text" });
+ return;
+ }
+
+ try {
+ const thread = await Discussion.findById(id);
+ if (!thread) {
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+
+ thread.comments.push({ username, text ,role });
+ await thread.save();
+ res.status(200).json({ message: "Comment added", thread });
+ } catch (err) {
+ console.error("Failed to comment on thread:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+// 6. Get a thread by ID
+router.get("/thread/:id", async (req, res) => {
+ const { id } = req.params;
+ try {
+ const thread = await Discussion.findById(id);
+ if (!thread) {
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+ res.status(200).json(thread);
+ } catch (err) {
+ console.error("Error fetching thread by ID:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+// POST /discuss/:threadId/comment/:commentId/reply
+router.post("/:threadId/comment/:commentId/reply", async (req, res) => {
+ const { threadId, commentId } = req.params;
+ const { username, text, role } = req.body;
+
+ if (!username || !text) {
+ res.status(400).json({ error: "Missing fields" });
+ return;
+ }
+
+ try {
+ const thread = await Discussion.findById(threadId);
+ if (!thread){
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+
+ const comment = thread.comments.id(commentId);
+ if (!comment){
+ res.status(404).json({ error: "Comment not found" });
+ return;
+ }
+
+ comment.replies.push({ username, text ,role });
+ await thread.save();
+
+ res.status(200).json({ message: "Reply added", thread });
+ } catch (err) {
+ console.error("Error replying to comment:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+// DELETE /discuss/thread/:threadId/comment/:commentId
+router.delete("/thread/:threadId/comment/:commentId", async (req, res) => {
+ const { threadId, commentId } = req.params;
+ const { username, role } = req.body; // Expecting role = 'student' | 'educator'
+
+ if (!username || !role) {
+ res.status(400).json({ error: "Missing username or role" });
+ return;
+ }
+
+ try {
+ const thread = await Discussion.findById(threadId);
+ if (!thread) {
+
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+
+ const comment = thread.comments.id(commentId);
+
+ if (!comment) {
+ res.status(404).json({ error: "Comment not found" });
+ return;
+ }
+
+ const isEducator = role === "educator";
+ const isCommentOwner = comment.username === username;
+
+ if (!isEducator && !isCommentOwner) {
+ res.status(403).json({ error: "Unauthorized to delete this comment" });
+ return;
+ }
+
+ // Remove the comment
+ thread.comments.pull(commentId);
+ // If no comments remain, delete the thread
+ if (thread.comments.length === 0) {
+ await Discussion.findByIdAndDelete(threadId);
+ res.status(200).json({ message: "Comment deleted. Thread also deleted as it had no comments left." });
+ return;
+ }
+ await thread.save();
+
+ res.status(200).json({ message: "Comment deleted", thread });
+ } catch (err) {
+ console.error("Failed to delete comment:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+// DELETE /discuss/thread/:threadId/comment/:commentId/reply/:replyId
+router.delete("/thread/:threadId/comment/:commentId/reply/:replyId", async (req, res) => {
+ const { threadId, commentId, replyId } = req.params;
+ const { username, role } = req.body; // Expecting role = 'student' | 'educator'
+
+ if (!username || !role) {
+ res.status(400).json({ error: "Missing username or role" });
+ return;
+ }
+
+ try {
+ const thread = await Discussion.findById(threadId);
+ if (!thread) {
+ res.status(404).json({ error: "Thread not found" });
+ return;
+ }
+
+ const comment = thread.comments.id(commentId);
+ if (!comment) {
+ res.status(404).json({ error: "Comment not found" });
+ return;
+ }
+
+ const reply = comment.replies.id(replyId);
+ if (!reply) {
+ res.status(404).json({ error: "Reply not found" });
+ return;
+ }
+ const isEducator = role === "educator";
+ const isReplyOwner = reply.username === username;
+ if (!isEducator && !isReplyOwner) {
+ res.status(403).json({ error: "Unauthorized to delete this reply" });
+ return;
+ }
+ // Remove the reply
+ comment.replies.pull(replyId);
+ await thread.save();
+ res.status(200).json({ message: "Reply deleted", thread });
+ } catch (err) {
+ console.error("Failed to delete reply:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+}
+);
+
+router.post("/ask", async (req, res) => {
+ const { userId, title, body, topic } = req.body;
+ if (!userId || !title || !body || !topic) {
+ res.status(400).json({ error: "All fields are required" });
+ return;
+ }
+ try {
+ const newThread = new Discussion({
+ topic,
+ createdBy: userId,
+ title,
+ body,
+ comments: [{ username: userId, text: body }],
+ });
+ await newThread.save();
+ res.status(201).json({ message: "Question posted successfully", threadId: newThread._id });
+ } catch (err) {
+ console.error("Error posting question:", err);
+ res.status(500).json({ error: "Internal server error" });
+ }
+});
+
+
+export default router;
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/routes/educator.ts b/team-bhavitha-dsarecommender/server/src/routes/educator.ts
new file mode 100644
index 000000000..442ed579e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/educator.ts
@@ -0,0 +1,24 @@
+import express from "express";
+import User from "../models/users";
+
+const router = express.Router();
+
+
+router.get("/educator/students", async (req, res) => {
+ try {
+ const students = await User.find({
+ $or: [
+ { role: "student" },
+ { role: { $exists: false } },
+ { role: null },
+ ],
+ }).select("username lastActive progress mastery");
+
+ res.json(students);
+ } catch (error) {
+ console.error("Error fetching students:", error);
+ res.status(500).json({ error: "Failed to fetch students" });
+ }
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/explore.ts b/team-bhavitha-dsarecommender/server/src/routes/explore.ts
new file mode 100644
index 000000000..b3783f7f3
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/explore.ts
@@ -0,0 +1,60 @@
+// routes/explore.ts
+import express from "express";
+import Concept from "../models/concepts"; // Your Mongoose model
+import mongoose from "mongoose";
+import { generateStructuredNotes } from "../utils/generateStructuredNotes";
+import { getTextFromPdfStream } from "../utils/pdfExtractor";
+const router = express.Router();
+
+// GET /api/explore/:topic
+router.get("/:topic", async (req, res) => {
+ const { topic } = req.params;
+ console.log(`π‘ Incoming explore request for topic: ${topic}`);
+ const db = mongoose.connection.db;
+ if (!db) {
+ res.status(500).json({ error: "Database connection not established" });
+ return;
+ }
+ console.log(`π’ Database connection established for explore route`);
+ try {
+ // const concept = await Concept.findOne({ name: new RegExp(`^${topic}$`, "i") });
+
+ // if (!concept) {
+ // res.status(404).json({ error: "Concept not found" });
+ // return;
+ // }
+ const mapping = await db.collection("topic_mappings").findOne({topic});
+ if (!mapping) {
+ console.log("π΄ Topic not found in topic_mappings");
+ res.status(404).json({ error: "Topic not found in mapping" });
+ return;
+ }
+ console.log(`π’ Found mapping for topic: ${topic} β PDF: ${mapping.pdf}`);
+ const file = await db.collection("pdfs.files").findOne({ filename: mapping.pdf });
+ if (!file) {
+ console.log("π΄ PDF file not found for topic:", topic);
+ res.status(404).json({ error: "PDF file not found" });
+ return;
+ }
+ console.log(`π’ Found PDF file for topic: ${topic} with ID: ${file._id}`);
+ const bucket = new mongoose.mongo.GridFSBucket(db, { bucketName: "pdfs" });
+ const stream = bucket.openDownloadStream(file._id);
+ const text = await getTextFromPdfStream(stream);
+ if (!text) {
+ console.log("π΄ No text extracted from PDF for topic:", topic);
+ res.status(500).json({ error: "Failed to extract text from PDF" });
+ return;
+ }
+ console.log(`π’ Successfully extracted text from PDF for topic: ${topic}`);
+
+ const structuredNotes = await generateStructuredNotes(text, topic);
+ console.log(`π’ Successfully generated structured notes for topic: ${topic}`);
+ res.json(structuredNotes);
+ //res.json(concept);
+ } catch (err) {
+ console.error("Explore route error:", err);
+ res.status(500).json({ error: "Server error" });
+ }
+});
+
+export default router;
diff --git a/server/src/routes/learningPath.ts b/team-bhavitha-dsarecommender/server/src/routes/learningPath.ts
similarity index 100%
rename from server/src/routes/learningPath.ts
rename to team-bhavitha-dsarecommender/server/src/routes/learningPath.ts
diff --git a/team-bhavitha-dsarecommender/server/src/routes/question.ts b/team-bhavitha-dsarecommender/server/src/routes/question.ts
new file mode 100644
index 000000000..08ba102a3
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/question.ts
@@ -0,0 +1,32 @@
+import express from "express";
+import AskedQuestion from "../models/AskedQuestion";
+
+const router = express.Router();
+
+// User asks a question
+router.post("/", async (req, res) => {
+ const { topic, questionIndex, questionText, askedBy } = req.body;
+
+ const entry = await AskedQuestion.create({
+ topic,
+ questionIndex,
+ questionText,
+ askedBy,
+ });
+
+ res.status(201).json(entry);
+});
+
+// Educator answers
+router.post("/answer/:id", async (req, res) => {
+ const { response } = req.body;
+ const question = await AskedQuestion.findByIdAndUpdate(
+ req.params.id,
+ { response, isAnswered: true },
+ { new: true }
+ );
+
+ res.status(200).json(question);
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/quiz.ts b/team-bhavitha-dsarecommender/server/src/routes/quiz.ts
new file mode 100644
index 000000000..93f5f8ca8
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/quiz.ts
@@ -0,0 +1,56 @@
+import express from "express";
+import mongoose from "mongoose";
+import { getTextFromPdfStream } from "../utils/pdfExtractor";
+import { generateQuizFromText } from "../utils/quizGenerator";
+
+const router = express.Router();
+
+router.get("/quiz/:topic", async (req, res) => {
+ const { topic } = req.params;
+ console.log(`π‘ Incoming quiz request for topic: ${topic}`);
+ const db = mongoose.connection.db;
+
+ if (!db) {
+ res.status(500).json({ error: "Database connection not established" });
+ return;
+ }
+
+ try {
+ const mapping = await db.collection("topic_mappings").findOne({ topic });
+ if (!mapping){
+ console.log("π΄ Topic not found in topic_mappings");
+ res.status(404).json({ error: "Topic not found in mapping" })
+ return;
+ }
+ console.log(`π’ Found mapping for topic β PDF: ${mapping.pdf}`);
+ const file = await db.collection("pdfs.files").findOne({ filename: mapping.pdf });
+ if (!file){
+ console.log("π΄ PDF file not found for topic:", topic);
+ res.status(404).json({ error: "PDF file not found" });
+ return;
+ }// res.status(404).json({ error: "PDF not found" });
+ console.log(`π’ Found PDF file for topic: ${topic} with ID: ${file._id}`);
+
+ const bucket = new mongoose.mongo.GridFSBucket(db, { bucketName: "pdfs" });
+ const stream = bucket.openDownloadStream(file._id);
+
+ const text = await getTextFromPdfStream(stream);
+ if (!text) {
+ console.log("π΄ No text extracted from PDF for topic:", topic);
+ res.status(500).json({ error: "Failed to extract text from PDF" });
+ return;
+ }
+ console.log(`π’ Successfully extracted text from PDF for topic: ${topic}`);
+
+ const formattedQuiz = await generateQuizFromText(text, topic);
+
+ console.log(`π’ Successfully generated quiz for topic: ${topic}`);
+
+ res.json(formattedQuiz);
+ } catch (err) {
+ console.error("Quiz generation error:", err);
+ res.status(500).json({ error: "Server error during quiz generation" });
+ }
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/quizHistory.ts b/team-bhavitha-dsarecommender/server/src/routes/quizHistory.ts
new file mode 100644
index 000000000..ac3d8119d
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/quizHistory.ts
@@ -0,0 +1,22 @@
+// routes/quizHistory.ts
+import express from "express";
+import QuizResult from "../models/QuizResult";
+import { ReturnDocument } from "mongodb";
+
+const router = express.Router();
+
+router.get("/:username", async (req, res) => {
+ const { username } = req.params;
+
+ try {
+ const results = await QuizResult.find({ username }).sort({ createdAt: -1 });
+ res.json(results);
+ return;
+ } catch (err) {
+ console.error("Error fetching quiz history:", err);
+ res.status(500).json({ error: "Failed to fetch quiz history" });
+ return;
+ }
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/quizSubmit.ts b/team-bhavitha-dsarecommender/server/src/routes/quizSubmit.ts
new file mode 100644
index 000000000..0ecde9318
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/quizSubmit.ts
@@ -0,0 +1,53 @@
+import express from "express";
+import QuizResult from "../models/QuizResult";
+
+const router = express.Router();
+
+router.post("/quiz/submit", async (req, res) => {
+ const { topic, username, answers, _correctAnswers } = req.body;
+
+ if (!topic || !username || !Array.isArray(answers) || !Array.isArray(_correctAnswers)) {
+ res.status(400).json({ error: "Missing required fields" });
+ return;
+ }
+
+ try {
+ const total = _correctAnswers.length;
+ let correctCount = 0;
+
+ for (let i = 0; i < total; i++) {
+ if (answers[i] === _correctAnswers[i]) {
+ correctCount++;
+ }
+ }
+
+ const score = (correctCount / total) * 100;
+ const mastery = Math.max(0.1, Math.min(0.9, 1 - score / 100));
+
+ // β
Save result to DB using your schema
+ await QuizResult.create({
+ username,
+ topic,
+ score,
+ mastery,
+ answers,
+ correctAnswers: _correctAnswers
+ });
+
+ // β
Response for frontend
+ res.json({
+ topic,
+ score,
+ userAnswers: answers,
+ correctAnswers: _correctAnswers,
+ masteryUpdate: {
+ [topic]: mastery
+ }
+ });
+ } catch (err) {
+ console.error("Quiz submission error:", err);
+ res.status(500).json({ error: "Failed to submit quiz" });
+ }
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/recommendation.ts b/team-bhavitha-dsarecommender/server/src/routes/recommendation.ts
new file mode 100644
index 000000000..b294a8ef6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/recommendation.ts
@@ -0,0 +1,24 @@
+import express from "express";
+import { findShortestPath } from "../utils/shortestPath";
+
+const router = express.Router();
+
+router.post("/", (req, res) => {
+ const { start, end } = req.body;
+
+ if (!start || !end) {
+ res.status(400).json({ error: "Start and end topics are required" });
+ return;
+ }
+
+ const path = findShortestPath(start, end);
+
+ if (!path) {
+ res.status(404).json({ error: "No path found" });
+ return;
+ }
+
+ res.json({ path });
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/report.ts b/team-bhavitha-dsarecommender/server/src/routes/report.ts
new file mode 100644
index 000000000..aa08246e0
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/report.ts
@@ -0,0 +1,20 @@
+import express from "express";
+import QuestionReport from "../models/QuestionReport";
+
+const router = express.Router();
+
+router.post("/", async (req, res) => {
+ const { topic, questionIndex, questionText, reportedBy, reason } = req.body;
+
+ const report = await QuestionReport.create({
+ topic,
+ questionIndex,
+ questionText,
+ reportedBy,
+ reason,
+ });
+
+ res.status(201).json({ message: "Report submitted", report });
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/routes/uploadPdf.ts b/team-bhavitha-dsarecommender/server/src/routes/uploadPdf.ts
new file mode 100644
index 000000000..639364f06
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/routes/uploadPdf.ts
@@ -0,0 +1,32 @@
+// routes/uploadPdf.ts
+import express from "express";
+import multer from "multer";
+import { GridFsStorage } from "multer-gridfs-storage";
+
+import mongoose from "mongoose";
+
+const router = express.Router();
+
+//@ts-ignore
+const storage = new GridFsStorage({
+ url: process.env.MONGO_URI!,
+ file: (req, file) => {
+ const { topic } = req.body;
+ return {
+ filename: file.originalname,
+ metadata: { topic },
+ bucketName: "pdfs",
+ };
+ },
+});
+//@ts-ignore
+const upload = multer({ storage });
+
+router.post("/upload-pdf", upload.single("pdf"), (req, res) => {
+ res.status(201).json({
+ message: "PDF uploaded successfully",
+ file: req.file,
+ });
+});
+
+export default router;
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/addEIDs.ts b/team-bhavitha-dsarecommender/server/src/scripts/addEIDs.ts
new file mode 100644
index 000000000..99b7d2321
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/addEIDs.ts
@@ -0,0 +1,21 @@
+// scripts/addEIDs.ts
+import mongoose from "mongoose";
+import EducatorID from "../models/EducatorID";
+import dotenv from "dotenv";
+
+dotenv.config();
+
+(async () => {
+ await mongoose.connect(process.env.MONGO_URI || "");
+
+ const eids = [
+ "1234567890123456",
+ "1111222233334444",
+ "5555666677778888"
+ ];
+
+ await EducatorID.insertMany(eids.map(eid => ({ eid })));
+
+ console.log("EIDs inserted");
+ mongoose.disconnect();
+})();
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/generate-chunks.ts b/team-bhavitha-dsarecommender/server/src/scripts/generate-chunks.ts
new file mode 100644
index 000000000..42414ffd2
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/generate-chunks.ts
@@ -0,0 +1,58 @@
+// server/scripts/generateChunks.ts
+
+import dotenv from "dotenv";
+dotenv.config();
+
+import fs from "fs";
+import path from "path";
+import { extractTextFromPDF } from "../utils/pdfParser";
+import { embedChunk } from "../utils/embeddingGenerator";
+import { topicMap } from "../utils/topicMap";
+
+const OUTPUT_PATH = path.join(__dirname, "../data/chunks.json");
+
+// Utility to split text into chunks
+function chunkText(text: string, chunkSize = 500): string[] {
+ const sentences = text.split(/(?<=[.?!])\s+/);
+ const chunks: string[] = [];
+
+ let current = "";
+ for (const sentence of sentences) {
+ if ((current + sentence).length > chunkSize) {
+ if (current) chunks.push(current.trim());
+ current = sentence;
+ } else {
+ current += " " + sentence;
+ }
+ }
+ if (current) chunks.push(current.trim());
+ return chunks;
+}
+
+async function generateChunks() {
+ const allChunks: any[] = [];
+
+ for (const [topic, pdfPath] of Object.entries(topicMap)) {
+ const fullPath = path.resolve(pdfPath);
+ const text = await extractTextFromPDF(fullPath);
+ const chunks = chunkText(text);
+
+ for (const chunk of chunks) {
+ const embedding = await embedChunk(chunk);
+ allChunks.push({
+ topic,
+ content: chunk,
+ embedding,
+ });
+ }
+
+ console.log(`β
Processed: ${topic}`);
+ }
+
+ fs.writeFileSync(OUTPUT_PATH, JSON.stringify(allChunks, null, 2));
+ console.log(`\nπ chunks.json saved to: ${OUTPUT_PATH}`);
+}
+
+generateChunks().catch((err) => {
+ console.error("β Error in generating chunks:", err);
+});
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/generateChunksFromConceptMap.ts b/team-bhavitha-dsarecommender/server/src/scripts/generateChunksFromConceptMap.ts
new file mode 100644
index 000000000..079a75947
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/generateChunksFromConceptMap.ts
@@ -0,0 +1,61 @@
+import fs from "fs";
+import path from "path";
+
+const concept_map: Record = {
+ "What is computation?": ["Computation", "Algorithms", "Problem Solving"],
+ "Branching and Iteration": ["Conditionals", "Loops", "Control Flow"],
+ "String Manipulation, Guess and Check, Approximations, Bisection": [
+ "String Manipulation",
+ "Guess and Check",
+ "Approximation",
+ "Bisection Search",
+ ],
+ "Decomposition, Abstractions, Functions": [
+ "Decomposition",
+ "Abstraction",
+ "Functions",
+ ],
+ "Tuples, Lists, Aliasing, Mutability, Cloning": [
+ "Tuples",
+ "Lists",
+ "Aliasing",
+ "Mutability",
+ "Cloning",
+ ],
+ "Recursion, Dictionaries": ["Recursion", "Dictionaries"],
+ "Testing, Debugging, Exceptions, Assertions": [
+ "Testing",
+ "Debugging",
+ "Exceptions",
+ "Assertions",
+ ],
+ "Object Oriented Programming": ["Classes", "OOP", "Encapsulation"],
+ "Python Classes and Inheritance": [
+ "Inheritance",
+ "Subclasses",
+ "Class Hierarchies",
+ ],
+ "Understanding Program Efficiency, Part 1": ["Big-O Notation", "Efficiency"],
+ "Understanding Program Efficiency, Part 2": ["Efficiency", "Space Complexity"],
+ "Searching and Sorting": ["Search Algorithms", "Sorting Algorithms"],
+};
+
+interface Chunk {
+ topic: string;
+ content: string;
+}
+
+const chunks: Chunk[] = [];
+
+for (const [lecture, topics] of Object.entries(concept_map)) {
+ for (const topic of topics) {
+ chunks.push({
+ topic,
+ content: `This topic appears in lecture: "${lecture}".`,
+ });
+ }
+}
+
+const outputPath = path.join(__dirname, "../src/data/chunks.json");
+fs.writeFileSync(outputPath, JSON.stringify(chunks, null, 2));
+console.log("β
chunks.json generated:", chunks.length, "entries");
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/model.ts b/team-bhavitha-dsarecommender/server/src/scripts/model.ts
new file mode 100644
index 000000000..2423fe81b
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/model.ts
@@ -0,0 +1,15 @@
+import { GoogleGenAI } from "@google/generative-ai";
+import dotenv from "dotenv";
+dotenv.config();
+
+const genAI = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! });
+
+async function listModels() {
+ const models = await genAI.listModels();
+ console.log("β
Available Gemini Models:");
+ for (const model of models) {
+ console.log(`β’ ${model.name}`);
+ }
+}
+
+listModels().catch(console.error);
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/seedConcepts.ts b/team-bhavitha-dsarecommender/server/src/scripts/seedConcepts.ts
new file mode 100644
index 000000000..8007630d2
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/seedConcepts.ts
@@ -0,0 +1,97 @@
+import mongoose from "mongoose";
+import dotenv from "dotenv";
+import fs from "fs";
+import path from "path";
+import Concept from "../models/concepts"; // adjust if needed
+
+dotenv.config();
+
+const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost:27017/learnflow";
+
+// Load concept graph JSON
+const graphPath = path.join(__dirname, "../data/concept_graph_full.json");
+const graph = JSON.parse(fs.readFileSync(graphPath, "utf-8"));
+
+interface Node {
+ id: string;
+}
+interface Link {
+ source: string;
+ target: string;
+}
+
+const defaultDescriptions: Record = {
+ "Conditionals": "Conditionals allow a program to execute different code based on logical conditions.",
+ "Loops": "Loops allow a program to repeat a block of code until a specific condition is met.",
+ "Recursion": "Recursion occurs when a function calls itself to solve a subproblem.",
+ // Add more if you want to override for certain topics
+};
+
+const defaultFacts: Record = {
+ "Conditionals": "They are key to implementing decision-making in programs.",
+ "Loops": "Loops help reduce redundancy and automate repetition.",
+ "Recursion": "Recursion simplifies problems that can be broken down into smaller subproblems.",
+};
+
+const defaultLectureMap: Record = {
+ "Conditionals": "Branching and Iteration",
+ "Loops": "Branching and Iteration",
+ "Recursion": "Recursion, Dictionaries",
+};
+
+const defaultExamples: Record = {
+ "Conditionals": ["if", "if-else", "nested if"],
+ "Loops": ["for loop", "while loop", "do-while loop"],
+ "Recursion": ["Factorial", "Fibonacci", "Tree Traversal"],
+};
+
+async function seedConcepts() {
+ await mongoose.connect(MONGODB_URI);
+ console.log("β
Connected to MongoDB");
+
+ const adjacency: Record> = {};
+ graph.nodes.forEach((node: Node) => {
+ adjacency[node.id] = new Set();
+ });
+
+ graph.links.forEach((link: Link) => {
+ adjacency[link.source].add(link.target);
+ adjacency[link.target].add(link.source); // mutual connection
+ });
+
+ interface ConceptDocument {
+ name: string;
+ description: string;
+ spotlight_fact: string;
+ lecture: string;
+ examples: string[];
+ related_topics: string[];
+ quiz_available: boolean;
+ }
+
+ const documents: ConceptDocument[] = graph.nodes.map((node: Node): ConceptDocument => {
+ const name: string = node.id;
+ return {
+ name,
+ description: defaultDescriptions[name] || `${name} is a fundamental concept in computer science.`,
+ spotlight_fact: defaultFacts[name] || `Did you know? ${name} is widely used in various applications.`,
+ lecture: defaultLectureMap[name] || "General Concepts",
+ examples: defaultExamples[name] || [],
+ related_topics: Array.from(adjacency[name]),
+ quiz_available: true,
+ };
+ });
+
+ await Concept.deleteMany({});
+ console.log("ποΈ Old concepts cleared.");
+
+ await Concept.insertMany(documents);
+ console.log("π± Concepts seeded successfully.");
+
+ process.exit(0);
+}
+
+seedConcepts().catch((err) => {
+ console.error("β Error during concept seeding:", err);
+ process.exit(1);
+});
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/uploadLectures.ts b/team-bhavitha-dsarecommender/server/src/scripts/uploadLectures.ts
new file mode 100644
index 000000000..8d58b1c23
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/uploadLectures.ts
@@ -0,0 +1,43 @@
+// scripts/uploadLectures.ts
+import fs from "fs";
+import path from "path";
+import mongoose from "mongoose";
+import { GridFSBucket } from "mongodb";
+import dotenv from "dotenv";
+
+//dotenv.config({ path: path.join(__dirname, "../../.env") });
+dotenv.config();
+
+
+const pdfDir = path.join(__dirname, "../data");
+
+async function uploadLectures() {
+ await mongoose.connect(process.env.MONGO_URI!);
+ const db = mongoose.connection.db;
+ if (!db) {
+ throw new Error("Database connection is not established.");
+ }
+ const bucket = new GridFSBucket(db, { bucketName: "pdfs" });
+
+ const lectureFiles = fs.readdirSync(pdfDir).filter(file => file.endsWith(".pdf"));
+
+ for (const file of lectureFiles) {
+ const stream = fs.createReadStream(path.join(pdfDir, file));
+ const uploadStream = bucket.openUploadStream(file);
+
+ stream.pipe(uploadStream);
+
+ await new Promise((resolve, reject) => {
+ uploadStream.on("finish", () => {
+ console.log(`β
Uploaded ${file}`);
+ resolve(null);
+ });
+ uploadStream.on("error", reject);
+ });
+ }
+
+ console.log("π All PDFs in /data uploaded to GridFS.");
+ process.exit();
+}
+
+uploadLectures();
diff --git a/team-bhavitha-dsarecommender/server/src/scripts/uploadTopicmap.ts b/team-bhavitha-dsarecommender/server/src/scripts/uploadTopicmap.ts
new file mode 100644
index 000000000..f33eda2d6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/scripts/uploadTopicmap.ts
@@ -0,0 +1,29 @@
+// scripts/uploadTopicMap.ts
+import mongoose from "mongoose";
+import { topicMap } from "../utils/topicMap"; // adjust path
+import dotenv from "dotenv";
+import path from "path";
+dotenv.config({ path: path.join(__dirname, "../../.env") });
+console.log(Object.keys(topicMap)); // β
should log all 30+ keys
+
+
+async function uploadTopicMappings() {
+ await mongoose.connect(process.env.MONGO_URI!);
+ const db = mongoose.connection.db;
+
+ if (!db) {
+ console.error("β Database connection is undefined.");
+ process.exit(1);
+ }
+ //await TopicMapping.deleteMany({});
+ const bulk = Object.entries(topicMap).map(([topic, path]) => {
+ const filename = path.split("/").pop();
+ return { topic, pdf: filename };
+ });
+
+ await db.collection("topic_mappings").insertMany(bulk);
+ console.log("β
Topic mappings uploaded.");
+ process.exit();
+}
+
+uploadTopicMappings();
diff --git a/team-bhavitha-dsarecommender/server/src/types/pdf-parse.d.ts b/team-bhavitha-dsarecommender/server/src/types/pdf-parse.d.ts
new file mode 100644
index 000000000..4cf4183a3
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/types/pdf-parse.d.ts
@@ -0,0 +1,16 @@
+// server/types/pdf-parse.d.ts
+
+declare module 'pdf-parse' {
+ interface PDFParseResult {
+ text: string;
+ numpages: number;
+ numrender: number;
+ info: any;
+ metadata: any;
+ version: string;
+ }
+
+ function pdfParse(dataBuffer: Buffer): Promise;
+
+ export = pdfParse;
+}
diff --git a/team-bhavitha-dsarecommender/server/src/types/quiz.ts b/team-bhavitha-dsarecommender/server/src/types/quiz.ts
new file mode 100644
index 000000000..dc7318e36
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/types/quiz.ts
@@ -0,0 +1,11 @@
+export interface MCQQuestion {
+ question: string;
+ options: string[];
+ correctAnswer: string;
+}
+
+export interface QuizSubmission {
+ topic: string;
+ username: string;
+ answers: string[];
+}
diff --git a/team-bhavitha-dsarecommender/server/src/uploads/1752344308666-762768640-Resume_Anurag_Kumar.pdf b/team-bhavitha-dsarecommender/server/src/uploads/1752344308666-762768640-Resume_Anurag_Kumar.pdf
new file mode 100644
index 000000000..435657e0e
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/uploads/1752344308666-762768640-Resume_Anurag_Kumar.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/uploads/1752344885526-92128057-_MMUPDF_0011049_100425.pdf b/team-bhavitha-dsarecommender/server/src/uploads/1752344885526-92128057-_MMUPDF_0011049_100425.pdf
new file mode 100644
index 000000000..733d56630
Binary files /dev/null and b/team-bhavitha-dsarecommender/server/src/uploads/1752344885526-92128057-_MMUPDF_0011049_100425.pdf differ
diff --git a/team-bhavitha-dsarecommender/server/src/utils/answerStore.ts b/team-bhavitha-dsarecommender/server/src/utils/answerStore.ts
new file mode 100644
index 000000000..d791458bd
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/answerStore.ts
@@ -0,0 +1,11 @@
+// server/utils/answerStore.ts
+
+const answerStore = new Map(); // topic β correctAnswers[]
+
+export function storeAnswers(topic: string, correctAnswers: string[]) {
+ answerStore.set(topic, correctAnswers);
+}
+
+export function getAnswers(topic: string): string[] | undefined {
+ return answerStore.get(topic);
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/buildGeminiPrompt.ts b/team-bhavitha-dsarecommender/server/src/utils/buildGeminiPrompt.ts
new file mode 100644
index 000000000..f4c43d97e
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/buildGeminiPrompt.ts
@@ -0,0 +1,19 @@
+export function buildBinaryQuestionPrompt(concept: string, content: string): string {
+ return `
+You are an educational assistant helping students assess their understanding of computer science concepts.
+
+**Task**: From the following learning material, generate a **single yes/no question** that tests understanding of the concept: **"${concept}"**.
+
+**Guidelines**:
+- Focus on conceptual understanding
+- Avoid factual, memory-based, or trivia questions
+- Ask reasoning-based questions (e.g., "Can you explain how a stack is used in recursion?")
+
+**Return only the question**, with no explanation or intro.
+
+---
+
+**Learning Content**:
+${content}
+`;
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/conceptGraph.ts b/team-bhavitha-dsarecommender/server/src/utils/conceptGraph.ts
new file mode 100644
index 000000000..db6e6bb6b
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/conceptGraph.ts
@@ -0,0 +1,41 @@
+import fs from "fs";
+import path from "path";
+
+type Graph = {
+ nodes: { id: string }[];
+ links: { source: string; target: string }[];
+};
+
+const graph: Graph = JSON.parse(
+ fs.readFileSync(path.join(__dirname, "../data/concept_graph_full.json"), "utf-8")
+);
+
+// Build reverse adjacency list (target β [sources])
+const prereqMap: Record = {};
+
+for (const { source, target } of graph.links) {
+ if (!prereqMap[target]) prereqMap[target] = [];
+ prereqMap[target].push(source);
+}
+
+// Recursive DFS to collect all prerequisites
+export function getAllPrerequisites(concept: string): string[] {
+ const visited = new Set();
+ const result: string[] = [];
+
+ function dfs(node: string) {
+ if (visited.has(node)) return;
+ visited.add(node);
+
+ const prereqs = prereqMap[node] || [];
+ for (const pre of prereqs) {
+ dfs(pre);
+ result.push(pre); // Add only after children β post-order
+ }
+ }
+
+ dfs(concept);
+
+ // Remove duplicates and reverse for earlier concepts first
+ return [...new Set(result.reverse())];
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/embeddingGenerator.ts b/team-bhavitha-dsarecommender/server/src/utils/embeddingGenerator.ts
new file mode 100644
index 000000000..3abdf7f91
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/embeddingGenerator.ts
@@ -0,0 +1,24 @@
+
+import dotenv from "dotenv";
+import path from "path";
+//dotenv.config({ path: path.join(__dirname, "../../.env") });
+dotenv.config();
+import { OpenAI } from "openai";
+
+
+console.log("OPENAI_API_KEY:", process.env.OPENAI_API_KEY);
+const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY});
+
+/**
+ * Generates an embedding vector for a given text using OpenAI's API.
+ * @param text A string chunk (β€8192 tokens recommended).
+ * @returns Embedding vector (array of floats).
+ */
+export async function embedChunk(text: string): Promise {
+ const response = await openai.embeddings.create({
+ model: "text-embedding-3-small", // or 'text-embedding-ada-002'
+ input: text,
+ });
+
+ return response.data[0].embedding;
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/extractContent.ts b/team-bhavitha-dsarecommender/server/src/utils/extractContent.ts
new file mode 100644
index 000000000..ba913d015
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/extractContent.ts
@@ -0,0 +1,29 @@
+// utils/questionGenerator.ts
+import { getTextFromPdfStream } from "./pdfExtractor";
+import { buildBinaryQuestionPrompt } from "./buildGeminiPrompt";
+import { generateBinaryQuestionWithGemini } from "./geminiClient";
+import mongoose from "mongoose";
+
+export async function getBinaryQuestionForTopic(topic: string): Promise {
+ const db = mongoose.connection.db;
+ if (!db) {
+ console.error("Database connection not established");
+ return null;
+ }
+ const mapping = await db.collection("topic_mappings").findOne({ topic });
+
+ if (!mapping) return null;
+
+ const file = await db.collection("pdfs.files").findOne({ filename: mapping.pdf });
+ if (!file) return null;
+
+ const bucket = new mongoose.mongo.GridFSBucket(db, { bucketName: "pdfs" });
+ const stream = bucket.openDownloadStream(file._id);
+ const text = await getTextFromPdfStream(stream);
+ if (!text) return null;
+
+ const prompt = buildBinaryQuestionPrompt(topic, text);
+ const question = await generateBinaryQuestionWithGemini(prompt);
+
+ return question;
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/geminiClient.ts b/team-bhavitha-dsarecommender/server/src/utils/geminiClient.ts
new file mode 100644
index 000000000..e9f9bc0bc
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/geminiClient.ts
@@ -0,0 +1,15 @@
+import { GoogleGenerativeAI } from "@google/generative-ai";
+
+const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
+const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
+
+export async function generateBinaryQuestionWithGemini(prompt: string): Promise {
+ try {
+ const result = await model.generateContent([prompt]);
+ const response = await result.response;
+ return response.text().trim();
+ } catch (err) {
+ console.error(" Gemini error:", err);
+ return "";
+ }
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/generateStructuredNotes.ts b/team-bhavitha-dsarecommender/server/src/utils/generateStructuredNotes.ts
new file mode 100644
index 000000000..761cd5d2c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/generateStructuredNotes.ts
@@ -0,0 +1,118 @@
+import { GoogleGenerativeAI } from "@google/generative-ai";
+import dotenv from "dotenv";
+import Concept from "../models/concepts";
+dotenv.config();
+
+const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
+
+export async function generateStructuredNotes(pdfText: string, topic: string) {
+ // Check cache
+ // const existing = await Concept.findOne({ name: new RegExp(`^${topic}$`, "i") });
+ // if (existing?.structuredNotes) {
+ // console.log("β
Returning cached notes for topic:", topic);
+ // return existing.structuredNotes;
+ // }
+
+ // Updated prompt with stricter JSON instructions
+ const prompt = `
+You are an educational AI assistant. Analyze the following lecture text about the topic "${topic}" and return a detailed semantic summary.
+
+Return a strictly valid JSON in the following structure WITHOUT any additional text, explanations, or markdown formatting:
+
+{
+ "description": "A concise explanation of the topic.",
+ "spotlight_fact": "A surprising or interesting fact about the topic.",
+ "lecture": "Lecture name or number, if available.",
+ "examples": ["Example 1", "Example 2"],
+ "related_topics": ["Topic A", "Topic B"],
+ "quiz_available": true,
+
+ "structuredNotes": {
+ "overview": "Brief summary of the topic.",
+ "keyConcepts": [
+ { "name": "Concept 1", "explanation": "..." },
+ { "name": "Concept 2", "explanation": "..." }
+ ],
+ "frequentlyUsed": ["Use case 1", "Use case 2"],
+ "commonPitfalls": ["Pitfall 1", "Pitfall 2"],
+ "bestPractices": ["Best practice 1", "Best practice 2"],
+ "latestReferences": ["Reference 1", "Reference 2"]
+ }
+}
+
+Here is the raw lecture content:
+"""${pdfText}"""
+`;
+
+ let rawTextContent = ''; // For error logging
+
+ try {
+ const model = genAI.getGenerativeModel({ model: "models/gemini-1.5-flash" });
+ const result = await model.generateContent(prompt);
+ const response = await result.response;
+ rawTextContent = await response.text(); // Store for possible error logging
+
+ // π Robust JSON extraction
+ let jsonString = rawTextContent.trim();
+
+ // 1. Handle markdown code blocks
+ if (jsonString.startsWith("```json")) {
+ jsonString = jsonString.slice(7);
+ // Remove trailing triple backticks if present
+ const endIndex = jsonString.lastIndexOf("```");
+ if (endIndex !== -1) {
+ jsonString = jsonString.substring(0, endIndex);
+ }
+ jsonString = jsonString.trim();
+ }
+ else if (jsonString.startsWith("```")) {
+ jsonString = jsonString.slice(3);
+ // Remove trailing triple backticks if present
+ const endIndex = jsonString.lastIndexOf("```");
+ if (endIndex !== -1) {
+ jsonString = jsonString.substring(0, endIndex);
+ }
+ jsonString = jsonString.trim();
+ }
+
+ // 2. Extract JSON between first { and last }
+ const startIdx = jsonString.indexOf('{');
+ const endIdx = jsonString.lastIndexOf('}');
+
+ if (startIdx === -1 || endIdx === -1) {
+ throw new Error("No JSON object found in response");
+ }
+
+ jsonString = jsonString.substring(startIdx, endIdx + 1);
+
+ const parsed = JSON.parse(jsonString);
+
+ // Fallbacks for missing fields
+ const fullConcept = {
+ name: topic,
+ description: parsed.description || "",
+ spotlight_fact: parsed.spotlight_fact || "",
+ lecture: parsed.lecture || "",
+ examples: parsed.examples || [],
+ related_topics: parsed.related_topics || [],
+ quiz_available: parsed.quiz_available ?? true,
+ structuredNotes: parsed.structuredNotes || {},
+ };
+
+ // await Concept.updateOne(
+ // { name: topic },
+ // { $set: fullConcept },
+ // { upsert: true }
+ // );
+
+ console.log("π’ Structured notes generated and cached for:", topic);
+ return fullConcept;
+ } catch (err) {
+ console.error("β Error generating structured notes:", err);
+
+ // Log raw response for debugging
+ console.error("Raw API response:", rawTextContent);
+
+ throw new Error("Failed to generate structured notes.");
+ }
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/src/utils/gridfs.ts b/team-bhavitha-dsarecommender/server/src/utils/gridfs.ts
new file mode 100644
index 000000000..7fdc03aaa
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/gridfs.ts
@@ -0,0 +1,13 @@
+// utils/gridfs.ts
+import mongoose from "mongoose";
+import { GridFSBucket } from "mongodb";
+
+let gfs: GridFSBucket;
+
+mongoose.connection.once("open", () => {
+ gfs = new mongoose.mongo.GridFSBucket(mongoose.connection.db!, {
+ bucketName: "pdfs"
+ });
+});
+
+export const getGFS = () => gfs;
diff --git a/team-bhavitha-dsarecommender/server/src/utils/pdfExtractor.ts b/team-bhavitha-dsarecommender/server/src/utils/pdfExtractor.ts
new file mode 100644
index 000000000..2b00393fe
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/pdfExtractor.ts
@@ -0,0 +1,16 @@
+import pdfParse from "pdf-parse";
+import { Readable } from "stream";
+
+export async function getTextFromPdfStream(stream: Readable): Promise {
+ const chunks: Uint8Array[] = [];
+
+ return new Promise((resolve, reject) => {
+ stream.on("data", (chunk) => chunks.push(chunk));
+ stream.on("end", async () => {
+ const buffer = Buffer.concat(chunks);
+ const data = await pdfParse(buffer);
+ resolve(data.text);
+ });
+ stream.on("error", reject);
+ });
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/pdfParser.ts b/team-bhavitha-dsarecommender/server/src/utils/pdfParser.ts
new file mode 100644
index 000000000..08281481a
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/pdfParser.ts
@@ -0,0 +1,16 @@
+import fs from "fs";
+// pdf-parse does not have official TypeScript types, so add a module declaration
+
+
+import pdf from "pdf-parse";
+
+/**
+ * Extracts raw text content from a PDF file.
+ * @param pdfPath Absolute path to the PDF file.
+ * @returns Text content from the PDF.
+ */
+export async function extractTextFromPDF(pdfPath: string): Promise {
+ const dataBuffer = fs.readFileSync(pdfPath);
+ const data = await pdf(dataBuffer);
+ return data.text;
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/quizGenerator.ts b/team-bhavitha-dsarecommender/server/src/utils/quizGenerator.ts
new file mode 100644
index 000000000..3e8aba534
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/quizGenerator.ts
@@ -0,0 +1,246 @@
+// // // import { OpenAI } from "openai";
+// // // import dotenv from "dotenv";
+// import path from "path";
+// // // dotenv.config({ path: path.join(__dirname, "../../.env") });
+
+
+// // // const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
+
+// // // interface RawQuestion {
+// // // question: string;
+// // // options: string[];
+// // // answer: string;
+// // // }
+
+// // // export async function generateQuizFromText(text: string, topic: string) {
+// // // const prompt = `
+// // // You are a quiz generation assistant.
+
+// // // Generate exactly 10 medium-to-hard multiple choice questions (MCQs) on the topic: "${topic}".
+// // // Each question must have 4 answer options and one correct answer.
+
+// // // Return ONLY valid JSON like:
+// // // [
+// // // {
+// // // "question": "....",
+// // // "options": ["A", "B", "C", "D"],
+// // // "answer": "..."
+// // // },
+// // // ...
+// // // ]
+
+// // // Lecture content:
+// // // """
+// // // ${text.slice(0, 4000)}
+// // // """
+// // // `;
+
+// // // const response = await openai.chat.completions.create({
+// // // model: "gpt-4o",
+// // // messages: [{ role: "user", content: prompt }],
+// // // temperature: 0.7,
+// // // });
+
+// // // const raw = response.choices[0].message.content || "[]";
+// // // const parsed: RawQuestion[] = JSON.parse(raw);
+
+// // // return {
+// // // questions: parsed.map(({ question, options }) => ({ question, options })),
+// // // _correctAnswers: parsed.map(({ answer }) => answer)
+// // // };
+// // // }
+// // import axios from "axios";
+// // import dotenv from "dotenv";
+// // dotenv.config({ path: path.join(__dirname, "../../.env") });
+
+// // const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent";
+
+// // export async function generateQuizFromText(text: string, topic: string) {
+// // const prompt = `
+// // Generate exactly 10 multiple choice questions (MCQs) of medium to hard difficulty on the topic: "${topic}".
+// // Each question should include:
+// // - a clear question
+// // - 4 options
+// // - one correct answer
+
+// // Respond ONLY in valid JSON format:
+// // [
+// // {
+// // "question": "...",
+// // "options": ["...", "...", "...", "..."],
+// // "answer": "..."
+// // }
+// // ]
+
+// // Context:
+// // """
+// // ${text.slice(0, 4000)}
+// // """`;
+
+// // try {
+// // const response = await axios.post(
+// // `${GEMINI_API_URL}?key=${process.env.GEMINI_API_KEY}`,
+// // {
+// // contents: [
+// // {
+// // parts: [{ text: prompt }],
+// // },
+// // ],
+// // }
+// // );
+
+// // // Assert the type of response.data to inform TypeScript about its structure
+// // const data = response.data as {
+// // candidates?: { content?: { parts?: { text?: string }[] } }[];
+// // };
+
+// // const textResponse = data.candidates?.[0]?.content?.parts?.[0]?.text;
+// // const json = textResponse?.replace(/```json|```/g, "").trim() ?? ""; // Remove code block wrappers
+
+// // const parsed = JSON.parse(json);
+
+// // return {
+// // questions: parsed.map(({ question, options }: any) => ({ question, options })),
+// // _correctAnswers: parsed.map((q: any) => q.answer),
+// // };
+// // } catch (err) {
+// // console.error("β Gemini API error:", err);
+// // throw new Error("Gemini quiz generation failed.");
+// // }
+// // }
+// import axios from "axios";
+// import dotenv from "dotenv";
+// dotenv.config({ path: path.join(__dirname, "../../.env") });
+
+// const GEMINI_API_URL =
+// "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent";
+
+// interface MCQ {
+// question: string;
+// options: string[];
+// answer: string;
+// }
+
+// export async function generateQuizFromText(text: string, topic: string) {
+// const prompt = `
+// Generate 10 MCQs on the topic "${topic}". Return them in this format:
+// [
+// {
+// "question": "...",
+// "options": ["A", "B", "C", "D"],
+// "answer": "..."
+// }
+// ]
+
+// Lecture content:
+// """
+// ${text.slice(0, 4000)}
+// """`;
+
+// try {
+// const res = await axios.post(
+// `${GEMINI_API_URL}?key=${process.env.GEMINI_API_KEY}`,
+// {
+// contents: [{ parts: [{ text: prompt }] }],
+// }
+// );
+
+// // Assert the type of res.data to inform TypeScript about its structure
+// const data = res.data as {
+// candidates?: { content?: { parts?: { text?: string }[] } }[];
+// };
+
+// const textResponse = data.candidates?.[0]?.content?.parts?.[0]?.text;
+// const cleaned = textResponse?.replace(/```json|```/g, "").trim() ?? "";
+// const parsed: MCQ[] = JSON.parse(cleaned);
+
+// return {
+// questions: parsed.map(({ question, options }) => ({ question, options })),
+// _correctAnswers: parsed.map((q) => q.answer),
+// };
+// } catch (err: any) {
+// console.warn("β οΈ Gemini failed. Using fallback questions.", err?.response?.data || err);
+
+// // β
Fallback mock data
+// const mockQuestions: MCQ[] = Array.from({ length: 10 }).map((_, i) => ({
+// question: `What is a mock question ${i + 1} on ${topic}?`,
+// options: ["Option A", "Option B", "Option C", "Option D"],
+// answer: "Option A",
+// }));
+
+// return {
+// questions: mockQuestions.map(({ question, options }) => ({ question, options })),
+// _correctAnswers: mockQuestions.map((q) => q.answer),
+// };
+// }
+// }
+// generateQuizFromText.ts
+import { GoogleGenAI } from "@google/genai";
+import dotenv from "dotenv";
+import path from "path";
+//dotenv.config({ path: path.join(__dirname, "../../.env") });
+dotenv.config();
+
+
+const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! });
+
+interface RawQuestion {
+ question: string;
+ options: string[];
+ answer: string;
+}
+
+export async function generateQuizFromText(text: string, topic: string) {
+ const prompt = `
+Generate exactly 10 multiple choice questions (MCQs) of medium to hard difficulty on the topic: "${topic}".
+
+Each question should have:
+- a clear question
+- 4 options
+- one correct answer
+
+Respond ONLY in valid JSON like:
+[
+ {
+ "question": "...",
+ "options": ["...", "...", "...", "..."],
+ "answer": "..."
+ }
+]
+
+Lecture content:
+"""
+${text.slice(0, 4000)}
+"""
+`;
+
+ try {
+ const result = await ai.models.generateContent({
+ model: "gemini-1.5-flash",
+ contents: [{ role: "user", parts: [{ text: prompt }] }],
+ });
+
+ const textResponse = result.candidates?.[0]?.content?.parts?.[0]?.text ?? "";
+ const cleaned = textResponse.replace(/```json|```/g, "").trim();
+ const parsed: RawQuestion[] = JSON.parse(cleaned);
+
+ return {
+ questions: parsed.map(({ question, options }) => ({ question, options })),
+ _correctAnswers: parsed.map((q) => q.answer),
+ };
+ } catch (err) {
+ console.warn("β οΈ Gemini failed, using fallback questions.\n", err);
+
+ //Fallback mock questions
+ const mockQuestions: RawQuestion[] = Array.from({ length: 10 }).map((_, i) => ({
+ question: `What is a mock question ${i + 1} on ${topic}?`,
+ options: ["Option A", "Option B", "Option C", "Option D"],
+ answer: "Option A",
+ }));
+
+ return {
+ questions: mockQuestions.map(({ question, options }) => ({ question, options })),
+ _correctAnswers: mockQuestions.map((q) => q.answer),
+ };
+ }
+}
diff --git a/team-bhavitha-dsarecommender/server/src/utils/ragEngine.ts b/team-bhavitha-dsarecommender/server/src/utils/ragEngine.ts
new file mode 100644
index 000000000..9abac939f
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/ragEngine.ts
@@ -0,0 +1,333 @@
+// import fs from "fs";
+// import path from "path";
+// import { OpenAI } from "openai";
+// import dotenv from "dotenv";
+
+// export interface MCQQuestion {
+// question: string;
+// options: string[];
+// correctAnswer: string;
+// }
+
+// // Load environment variables
+// dotenv.config({ path: path.join(__dirname, "../../.env") });
+
+// // 1. Load preprocessed chunks (simulating retrieval DB)
+// const chunks = JSON.parse(
+// fs.readFileSync(path.join(__dirname, "../data/chunks.json"), "utf-8")
+// ) as { topic: string; content: string }[];
+
+// // 2. Initialize OpenAI
+// const openai = new OpenAI({
+// apiKey: process.env.OPENAI_API_KEY,
+// });
+
+// // 3. Generate default MCQ questions for a topic
+// function generateDefaultQuestions(topic: string): MCQQuestion[] {
+// return [
+// {
+// question: `What is the main concept of ${topic}?`,
+// options: [
+// "It's a fundamental principle",
+// "It's an advanced technique",
+// "It's a theoretical concept",
+// "It's a practical application"
+// ],
+// correctAnswer: "It's a fundamental principle"
+// },
+// {
+// question: `How is ${topic} typically applied?`,
+// options: [
+// "In theoretical research",
+// "In practical applications",
+// "In both theory and practice",
+// "In neither theory nor practice"
+// ],
+// correctAnswer: "In both theory and practice"
+// },
+// {
+// question: `What is the primary benefit of understanding ${topic}?`,
+// options: [
+// "Better problem-solving ability",
+// "Improved technical skills",
+// "Enhanced theoretical knowledge",
+// "All of the above"
+// ],
+// correctAnswer: "All of the above"
+// }
+// ];
+// }
+
+// // 4. Parse OpenAI response into MCQ format
+// function parseOpenAIResponse(content: string): MCQQuestion[] | null {
+// try {
+// // First try to parse as JSON
+// try {
+// const parsed = JSON.parse(content);
+// if (Array.isArray(parsed) &&
+// parsed.every(q => q.question && Array.isArray(q.options) && q.correctAnswer)) {
+// return parsed;
+// }
+// } catch (e) {
+// console.log("Not JSON format, trying text parsing");
+// }
+
+// // Fallback: Try to parse formatted text
+// const questions = content.split(/\d+\.|Q\d+:/).filter(q => q.trim());
+// return questions.map(q => {
+// const lines = q.trim().split('\n').filter(l => l.trim());
+// const question = lines[0].trim();
+// const options = lines.slice(1, -1).map(l =>
+// l.replace(/^[A-D]\)|^[A-D]\.|^-/, '').trim()
+// );
+// const correctAnswer = options[0]; // Default to first option if not specified
+
+// return {
+// question,
+// options: options.length >= 4 ? options : [
+// "Option A",
+// "Option B",
+// "Option C",
+// "Option D"
+// ],
+// correctAnswer
+// };
+// });
+// } catch (error) {
+// console.error("Failed to parse OpenAI response:", error);
+// return null;
+// }
+// }
+
+// // 5. Retrieve content & generate questions
+// export async function generateQuizQuestions(topic: string): Promise {
+// if (!topic) {
+// console.warn("No topic provided");
+// return generateDefaultQuestions("general knowledge");
+// }
+
+// try {
+// // First try to find the topic in our chunks
+// const relevant = chunks.filter(chunk =>
+// chunk.topic.toLowerCase().includes(topic.toLowerCase())
+// );
+
+// const context = relevant.map(r => r.content).slice(0, 3).join("\n\n");
+
+// try {
+// const completion = await openai.chat.completions.create({
+// model: "gpt-3.5-turbo",
+// messages: [
+// {
+// role: "system",
+// content: `You are a quiz generator. Create 3 multiple-choice questions about the given topic.
+// Each question should have:
+// 1. A clear question
+// 2. Four options (A, B, C, D)
+// 3. One correct answer
+
+// Format as a JSON array of objects like:
+// [
+// {
+// "question": "Question text?",
+// "options": ["Option A", "Option B", "Option C", "Option D"],
+// "correctAnswer": "Option that is correct"
+// }
+// ]`
+// },
+// {
+// role: "user",
+// content: `Create MCQ questions about: ${topic}
+// Context: ${context || 'This is a topic in computer science or programming.'}`
+// }
+// ],
+// temperature: 0.7,
+// max_tokens: 1000,
+// });
+
+// const generatedText = completion.choices[0]?.message?.content || "";
+// const questions = parseOpenAIResponse(generatedText);
+
+// if (questions && questions.length > 0) {
+// return questions;
+// }
+
+// } catch (openaiError) {
+// console.error("OpenAI API error:", openaiError);
+// }
+
+// // If we get here, either OpenAI failed or returned invalid format
+// return generateDefaultQuestions(topic);
+
+// } catch (error) {
+// console.error("Error in generateQuizQuestions:", error);
+// return generateDefaultQuestions(topic);
+// }
+// }
+
+// server/utils/ragEngine.ts
+
+import { OpenAI } from "openai";
+import path from "path";
+import fs from "fs";
+import dotenv from "dotenv";
+
+export interface MCQQuestion {
+ question: string;
+ options: string[];
+ correctAnswer: string;
+}
+
+// Load environment variables
+dotenv.config({ path: path.join(__dirname, "../../.env") });
+
+// 1. Load preprocessed chunks (simulating retrieval DB)
+const chunks = JSON.parse(
+ fs.readFileSync(path.join(__dirname, "../data/chunks.json"), "utf-8")
+) as { topic: string; content: string }[];
+
+// 2. Initialize OpenAI
+const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
+
+// 3. Generate default MCQ questions for a topic
+function generateDefaultQuestions(topic: string): MCQQuestion[] {
+ return [
+ {
+ question: `What is the main concept of ${topic}?`,
+ options: [
+ "It's a fundamental principle",
+ "It's an advanced technique",
+ "It's a theoretical concept",
+ "It's a practical application"
+ ],
+ correctAnswer: "It's a fundamental principle"
+ },
+ {
+ question: `How is ${topic} typically applied?`,
+ options: [
+ "In theoretical research",
+ "In practical applications",
+ "In both theory and practice",
+ "In neither theory nor practice"
+ ],
+ correctAnswer: "In both theory and practice"
+ },
+ {
+ question: `What is the primary benefit of understanding ${topic}?`,
+ options: [
+ "Better problem-solving ability",
+ "Improved technical skills",
+ "Enhanced theoretical knowledge",
+ "All of the above"
+ ],
+ correctAnswer: "All of the above"
+ }
+ ];
+}
+
+// 4. Parse OpenAI response into MCQ format
+function parseOpenAIResponse(content: string): MCQQuestion[] | null {
+ try {
+ // First try to parse as JSON
+ try {
+ const parsed = JSON.parse(content);
+ if (Array.isArray(parsed) &&
+ parsed.every(q => q.question && Array.isArray(q.options) && q.correctAnswer)) {
+ return parsed;
+ }
+ } catch (e) {
+ console.log("Not JSON format, trying text parsing");
+ }
+
+ // Fallback: Try to parse formatted text
+ const questions = content.split(/\d+\.|Q\d+:/).filter(q => q.trim());
+ return questions.map(q => {
+ const lines = q.trim().split('\n').filter(l => l.trim());
+ const question = lines[0].trim();
+ const options = lines.slice(1, -1).map(l =>
+ l.replace(/^[A-D]\)|^[A-D]\.|^-/, '').trim()
+ );
+ const correctAnswer = options[0]; // Default to first option if not specified
+
+ return {
+ question,
+ options: options.length >= 4 ? options : [
+ "Option A",
+ "Option B",
+ "Option C",
+ "Option D"
+ ],
+ correctAnswer
+ };
+ });
+ } catch (error) {
+ console.error("Failed to parse OpenAI response:", error);
+ return null;
+ }
+}
+
+// 5. Retrieve content & generate questions
+export async function generateQuizQuestions(topic: string): Promise {
+ if (!topic) {
+ console.warn("No topic provided");
+ return generateDefaultQuestions("general knowledge");
+ }
+
+ try {
+ // First try to find the topic in our chunks
+ const relevant = chunks.filter(chunk =>
+ chunk.topic.toLowerCase().includes(topic.toLowerCase())
+ );
+
+ const context = relevant.map(r => r.content).slice(0, 3).join("\n\n");
+
+ try {
+ const completion = await openai.chat.completions.create({
+ model: "gpt-3.5-turbo",
+ messages: [
+ {
+ role: "system",
+ content: `You are a quiz generator. Create 3 multiple-choice questions about the given topic.
+ Each question should have:
+ 1. A clear question
+ 2. Four options (A, B, C, D)
+ 3. One correct answer
+
+ Format as a JSON array of objects like:
+ [
+ {
+ "question": "Question text?",
+ "options": ["Option A", "Option B", "Option C", "Option D"],
+ "correctAnswer": "Option that is correct"
+ }
+ ]`
+ },
+ {
+ role: "user",
+ content: `Create MCQ questions about: ${topic}
+ Context: ${context || 'This is a topic in computer science or programming.'}`
+ }
+ ],
+ temperature: 0.7,
+ max_tokens: 1000,
+ });
+
+ const generatedText = completion.choices[0]?.message?.content || "";
+ const questions = parseOpenAIResponse(generatedText);
+
+ if (questions && questions.length > 0) {
+ return questions;
+ }
+
+ } catch (openaiError) {
+ console.error("OpenAI API error:", openaiError);
+ }
+
+ // If we get here, either OpenAI failed or returned invalid format
+ return generateDefaultQuestions(topic);
+
+ } catch (error) {
+ console.error("Error in generateQuizQuestions:", error);
+ return generateDefaultQuestions(topic);
+ }
+}
diff --git a/server/src/utils/shortestPath.ts b/team-bhavitha-dsarecommender/server/src/utils/shortestPath.ts
similarity index 100%
rename from server/src/utils/shortestPath.ts
rename to team-bhavitha-dsarecommender/server/src/utils/shortestPath.ts
diff --git a/team-bhavitha-dsarecommender/server/src/utils/topicMap.ts b/team-bhavitha-dsarecommender/server/src/utils/topicMap.ts
new file mode 100644
index 000000000..72c6dc8e1
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/src/utils/topicMap.ts
@@ -0,0 +1,38 @@
+export const topicMap: Record = {
+ "Computation": "../data/lecture1.pdf",
+ "Algorithms": "../data/lecture1.pdf",
+ "Problem Solving": "../data/lecture1.pdf",
+ "Conditionals": "../data/lecture2.pdf",
+ "Loops": "../data/lecture2.pdf",
+ "control flow": "../data/lecture2.pdf",
+ "String Manipulation": "../data/lecture3.pdf",
+ "Guess and Check": "../data/lecture3.pdf",
+ "Approximation" : "../data/lecture3.pdf",
+ "Bisection Search": "../data/lecture3.pdf",
+ "Decomposition": "../data/lecture4.pdf",
+ "Abstraction" : "../data/lecture4.pdf",
+ "Functions": "../data/lecture4.pdf",
+ "Tuples" : "../data/lecture5.pdf",
+ "Lists": "../data/lecture5.pdf",
+ "Aliasing" : "../data/lecture5.pdf",
+ "Mutability": "../data/lecture5.pdf",
+ "Cloning" : "../data/lecture5.pdf",
+ "Recursion": "../data/lecture6.pdf",
+ "Dictionaries": "../data/lecture6.pdf",
+ "Testing" : "../data/lecture7.pdf",
+ "Debugging": "../data/lecture7.pdf",
+ "Exceptions": "../data/lecture7.pdf",
+ "Assertions": "../data/lecture7.pdf",
+ "Classes" : "../data/lecture8.pdf",
+ "OOP" : "../data/lecture8.pdf",
+ "Encapsulation": "../data/lecture8.pdf",
+ "Inheritance": "../data/lecture9.pdf",
+ "Subclasses": "../data/lecture9.pdf",
+ "Class Hierarchies": "../data/lecture9.pdf",
+ "Big-O Notation": "../data/lecture10.pdf",
+ "Efficiency" : "../data/lecture10.pdf",
+ "Search Algorithms": "../data/lecture12.pdf",
+ "Space Complexity": "../data/lecture10.pdf",
+ "Complexity Analysis": "../data/lecture11.pdf",
+ "Sorting Algorithms": "../data/lecture12.pdf",
+}
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/standalone_tests/reinsert_data.ts b/team-bhavitha-dsarecommender/server/standalone_tests/reinsert_data.ts
new file mode 100644
index 000000000..244fece7c
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/standalone_tests/reinsert_data.ts
@@ -0,0 +1,311 @@
+// reinsert_data.ts - FINAL CLEANED VERSION
+
+import mongoose, { Schema, Document } from 'mongoose';
+import dotenv from 'dotenv';
+
+dotenv.config(); // Load environment variables from .env
+
+// --- Configuration ---
+const MONGO_URI = process.env.MONGO_URI || "mongodb+srv://akssrf2025:Aks1234@cluster0.oek3we1.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
+const DATABASE_NAME = process.env.DATABASE_NAME || "LearnFlowDB";
+const COLLECTION_NAME = "concepts"; // THIS IS THE COLLECTION NAME THE SERVER USES
+
+// --- Mongoose Concept Model ---
+interface IConcept extends Document {
+ name: string;
+ description: string;
+ spotlight_fact: string;
+ lecture: string;
+ timestamp: Date;
+ source: string;
+}
+
+const ConceptSchema: Schema = new Schema({
+ name: { type: String, required: true, unique: true },
+ description: { type: String, required: true },
+ spotlight_fact: { type: String, required: true },
+ lecture: { type: String, required: true },
+ timestamp: { type: Date, default: Date.now },
+ source: { type: String, default: "Initial Data Re-insertion" },
+}, { collection: COLLECTION_NAME });
+
+const Concept = mongoose.models.Concept || mongoose.model('Concept', ConceptSchema);
+
+// --- Data to Re-insert ---
+// This array contains ALL the unique concepts and their facts
+// Total Concepts: 38 (4 new web dev + 34 original, excluding Efficiency Part 1/2)
+const conceptsToReinsert = [
+ // --- New Web Development Concepts (4 concepts) ---
+ {
+ name: "HTTP",
+ description: "Hypertext Transfer Protocol is the foundation of data communication for the World Wide Web.",
+ spotlight_fact: "HTTP is stateless, meaning each request from a client is independent of previous ones.",
+ lecture: "Networking Basics"
+ },
+ {
+ name: "REST APIs",
+ description: "Representational State Transfer (REST) is an architectural style for designing networked applications.",
+ spotlight_fact: "REST APIs commonly use standard HTTP methods (GET, POST, PUT, DELETE) for operations.",
+ lecture: "Web Development Concepts"
+ },
+ {
+ name: "Frontend Frameworks",
+ description: "Libraries or tools that provide a foundation for building the user interface of web applications.",
+ spotlight_fact: "Popular frontend frameworks include React, Angular, and Vue.js.",
+ lecture: "Frontend Development"
+ },
+ {
+ name: "Backend Frameworks",
+ description: "Libraries or tools that simplify the development of server-side logic and database interactions for web applications.",
+ spotlight_fact: "Node.js frameworks like Express.js are commonly used for building scalable APIs.",
+ lecture: "Backend Development"
+ },
+ // --- Original Concepts (34 concepts - 'Efficiency Part 1/2' removed, 'Big-O Notation' kept) ---
+ {
+ name: "Computation",
+ description: "Computation is the act of performing calculations or solving problems using a set of well-defined steps known as algorithms.",
+ spotlight_fact: "The foundations of computation stem from mathematics and logic, particularly Turing Machines and Lambda Calculus.",
+ lecture: "What is computation?"
+ },
+ {
+ name: "Algorithms",
+ description: "Algorithms are structured, step-by-step procedures designed to perform a task or solve a problem.",
+ spotlight_fact: "Every software application, from web browsers to video games, relies on algorithms to function.",
+ lecture: "What is computation?"
+ },
+ {
+ name: "Problem Solving",
+ description: "Problem solving involves analyzing a situation and creating an efficient algorithmic solution.",
+ spotlight_fact: "Effective problem solving is the cornerstone of successful programming.",
+ lecture: "What is computation?"
+ },
+ {
+ name: "Conditionals",
+ description: "Conditionals are statements that run different code blocks depending on whether a condition is true or false.",
+ spotlight_fact: "Conditionals empower programs to make decisions dynamically.",
+ lecture: "Branching and Iteration"
+ },
+ {
+ name: "Loops",
+ description: "Loops allow a program to repeat a block of code until a specific condition is met.",
+ spotlight_fact: "Loops help reduce redundancy and automate repetition.",
+ lecture: "Branching and Iteration"
+ },
+ {
+ name: "Control Flow",
+ description: "Control flow dictates the order in which individual statements, instructions, or function calls are executed.",
+ spotlight_fact: "Control flow structures include conditionals, loops, and function calls.",
+ lecture: "Branching and Iteration"
+ },
+ {
+ name: "String Manipulation",
+ description: "String manipulation involves processing and transforming text data.",
+ spotlight_fact: "Strings are one of the most commonly used data types in programming.",
+ lecture: "String Manipulation, Guess and Check, Approximations, Bisection"
+ },
+ {
+ name: "Guess and Check",
+ description: "Guess and check is a brute-force approach where solutions are tested one by one until the correct one is found.",
+ spotlight_fact: "Guess and check is often used when no efficient algorithm is known.",
+ lecture: "String Manipulation, Guess and Check, Approximations, Bisection"
+ },
+ {
+ name: "Approximation",
+ description: "Approximation refers to techniques that find close-enough answers instead of exact results, often for efficiency.",
+ spotlight_fact: "Approximate solutions are useful in problems with large solution spaces or floating-point operations.",
+ lecture: "String Manipulation, Guess and Check, Approximations, Bisection"
+ },
+ {
+ name: "Bisection Search",
+ description: "Bisection search repeatedly splits a sorted list or range in half to efficiently locate a target value.",
+ spotlight_fact: "Bisection reduces search complexity from linear to logarithmic.",
+ lecture: "String Manipulation, Guess and Check, Approximations, Bisection"
+ },
+ {
+ name: "Decomposition",
+ description: "Decomposition is the practice of breaking complex problems into smaller, more manageable parts.",
+ spotlight_fact: "Decomposition improves code readability and modularity.",
+ lecture: "Decomposition, Abstractions, Functions"
+ },
+ {
+ name: "Abstraction",
+ description: "Abstraction means hiding complex implementation details and showing only the essential features of a concept.",
+ spotlight_fact: "Abstraction allows programmers to work with higher-level representations.",
+ lecture: "Decomposition, Abstractions, Functions"
+ },
+ {
+ name: "Functions",
+ description: "Functions are reusable blocks of code that perform specific tasks and return results.",
+ spotlight_fact: "Functions promote code reusability and organization.",
+ lecture: "Decomposition, Abstractions, Functions"
+ },
+ {
+ name: "Tuples",
+ description: "Tuples are immutable sequences used to group multiple values in a single compound data type.",
+ spotlight_fact: "Tuples are ideal for storing fixed collections of heterogeneous data.",
+ lecture: "Tuples, Lists, Aliasing, Mutability, Cloning"
+ },
+ {
+ name: "Lists",
+ description: "Lists are mutable ordered sequences that can hold elements of any type.",
+ spotlight_fact: "Python lists dynamically resize and support slicing.",
+ lecture: "Tuples, Lists, Aliasing, Mutability, Cloning"
+ },
+ {
+ name: "Aliasing",
+ description: "Aliasing occurs when two variables refer to the same object in memory.",
+ spotlight_fact: "Changes made through one alias affect all others.",
+ lecture: "Tuples, Lists, Aliasing, Mutability, Cloning"
+ },
+ {
+ name: "Mutability",
+ description: "Mutability refers to whether an object can be modified after creation.",
+ spotlight_fact: "Lists are mutable; tuples are not.",
+ lecture: "Tuples, Lists, Aliasing, Mutability, Cloning"
+ },
+ {
+ name: "Cloning",
+ description: "Cloning creates a copy of an object, often to prevent shared references from causing unintended side effects.",
+ spotlight_fact: "Shallow vs deep cloning affects whether nested structures are copied.",
+ lecture: "Tuples, Lists, Aliasing, Mutability, Cloning"
+ },
+ {
+ name: "Recursion",
+ description: "Recursion occurs when a function calls itself to solve a problem by reducing it to smaller instances.",
+ spotlight_fact: "All recursive solutions can be rewritten iteratively, though not always elegantly.",
+ lecture: "Recursion, Dictionaries"
+ },
+ {
+ name: "Dictionaries",
+ description: "Dictionaries store key-value pairs for fast access, lookup, and insertion.",
+ spotlight_fact: "Dictionaries in Python are implemented using hash tables.",
+ lecture: "Recursion, Dictionaries"
+ },
+ {
+ name: "Testing",
+ description: "Testing verifies that code behaves as expected under various inputs.",
+ spotlight_fact: "Good testing includes both normal and edge cases.",
+ lecture: "Testing, Debugging, Exceptions, Assertions"
+ },
+ {
+ name: "Debugging",
+ description: "Debugging is the process of identifying and fixing errors or bugs in code.",
+ spotlight_fact: "Systematic debugging can drastically reduce development time.",
+ lecture: "Testing, Debugging, Exceptions, Assertions"
+ },
+ {
+ name: "Exceptions",
+ description: "Exceptions are runtime errors that disrupt normal program flow and can be caught with try-except blocks.",
+ spotlight_fact: "Handling exceptions prevents program crashes and improves robustness.",
+ lecture: "Testing, Debugging, Exceptions, Assertions"
+ },
+ {
+ name: "Assertions",
+ description: "Assertions are sanity checks that test assumptions made by the code during execution.",
+ spotlight_fact: "Assertions help catch bugs early by detecting unexpected behavior.",
+ lecture: "Testing, Debugging, Exceptions, Assertions"
+ },
+ {
+ name: "Classes",
+ description: "Classes are blueprints for creating objects that bundle data and behavior.",
+ spotlight_fact: "Classes enable object-oriented programming and code reuse.",
+ lecture: "Object Oriented Programming"
+ },
+ {
+ name: "OOP",
+ description: "Object-Oriented Programming (OOP) is a paradigm centered around objects that encapsulate data and behavior.",
+ spotlight_fact: "OOP enables modular, reusable, and scalable codebases.",
+ lecture: "Object Oriented Programming"
+ },
+ {
+ name: "Encapsulation",
+ description: "Encapsulation is the principle of restricting direct access to some components of an object.",
+ spotlight_fact: "Encapsulation protects internal state and promotes modular design.",
+ lecture: "Object Oriented Programming"
+ },
+ {
+ name: "Inheritance",
+ description: "Inheritance allows a class to inherit properties and methods from another class.",
+ spotlight_fact: "Inheritance promotes code reuse and logical hierarchy.",
+ lecture: "Python Classes and Inheritance"
+ },
+ {
+ name: "Subclasses",
+ description: "Subclasses are derived from parent classes and can override or extend their functionality.",
+ spotlight_fact: "Python supports multiple inheritance via subclassing.",
+ lecture: "Python Classes and Inheritance"
+ },
+ {
+ name: "Class Hierarchies",
+ description: "Class hierarchies organize classes in a tree structure to represent inheritance relationships.",
+ spotlight_fact: "Well-designed hierarchies simplify complex systems.",
+ lecture: "Python Classes and Inheritance"
+ },
+ {
+ name: "Big-O Notation", // KEPT THIS ONE!
+ description: "Big-O notation describes the upper bound of an algorithm's running time as input size grows.",
+ spotlight_fact: "Big-O helps evaluate and compare algorithmic efficiency.",
+ lecture: "Understanding Program Efficiency, Part 1"
+ },
+ {
+ name: "Space Complexity",
+ description: "Space complexity refers to the amount of memory an algorithm uses relative to input size.",
+ spotlight_fact: "Some problems are memory-bound rather than compute-bound.",
+ lecture: "Understanding Program Efficiency, Part 2"
+ },
+ {
+ name: "Search Algorithms",
+ description: "Search algorithms are techniques for finding elements in data structures or solving search problems.",
+ spotlight_fact: "Common search techniques include linear search, binary search, and graph traversal.",
+ lecture: "Searching and Sorting"
+ },
+ {
+ name: "Sorting Algorithms",
+ description: "Sorting algorithms arrange data in a particular order, often increasing efficiency for other operations.",
+ spotlight_fact: "Well-known sorting algorithms include bubble sort, merge sort, and quicksort.",
+ lecture: "Searching and Sorting"
+ }
+];
+
+// --- Main function to connect, re-insert, and disconnect ---
+async function reinsertData() {
+ // Removed 'let client: MongoClient | null = null;' as it's not used with Mongoose direct connect
+ try {
+ console.log("Attempting to connect to MongoDB for data re-insertion...");
+ console.log(`DEBUG: reinsert_data.ts using MONGO_URI: ${MONGO_URI}`);
+ console.log(`DEBUG: reinsert_data.ts targeting DATABASE_NAME: ${DATABASE_NAME}`);
+
+ await mongoose.connect(MONGO_URI, { dbName: DATABASE_NAME } as mongoose.ConnectOptions);
+ console.log("β
Successfully connected to MongoDB for re-insertion.");
+
+ const db = mongoose.connection.db; // Get the native MongoDB driver DB object
+ // Added check for db
+ if (db) {
+ console.log(`Connected to database: ${db.databaseName}`);
+ console.log(`Operating on collection: ${COLLECTION_NAME}`);
+ } else {
+ console.warn("WARN: Mongoose connection.db is not available yet.");
+ }
+
+
+ // 1. Delete all existing documents in the collection
+ const deleteResult = await Concept.deleteMany({});
+ console.log(`ποΈ Deleted ${deleteResult.deletedCount} existing concepts.`);
+
+ // 2. Insert new documents
+ const insertResult = await Concept.insertMany(conceptsToReinsert);
+ console.log(`β¨ Successfully re-inserted ${insertResult.length} new concepts.`);
+
+ } catch (error) {
+ console.error("β Error during data re-insertion:", error);
+ } finally {
+ // Ensure to close Mongoose connection if it was opened
+ if (mongoose.connection.readyState !== 0) { // Check if not disconnected
+ await mongoose.disconnect();
+ console.log("MongoDB connection closed.");
+ }
+ }
+}
+
+// Call the function to execute the data re-insertion
+reinsertData();
\ No newline at end of file
diff --git a/team-bhavitha-dsarecommender/server/standalone_tests/spotlight_server.ts b/team-bhavitha-dsarecommender/server/standalone_tests/spotlight_server.ts
new file mode 100644
index 000000000..eba0a5816
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/standalone_tests/spotlight_server.ts
@@ -0,0 +1,171 @@
+// standalone_tests/spotlight_server.ts - FINAL CLEANED VERSION
+
+import express, { Request, Response, RequestHandler } from 'express';
+import mongoose, { Schema, Document } from 'mongoose';
+import cors from 'cors';
+import dotenv from 'dotenv';
+
+dotenv.config(); // Load environment variables from .env
+
+const app = express();
+const port = process.env.SPOTLIGHT_PORT || 5001;
+
+// --- Middleware ---
+app.use(cors()); // Enable CORS for all routes (important for frontend to connect)
+app.use(express.json()); // Enable parsing JSON request bodies
+
+// --- Mongoose Concept Model ---
+// Interface representing the structure of a concept document in MongoDB
+interface IConcept extends Document {
+ name: string;
+ description?: string;
+ spotlight_fact?: string;
+ lecture?: string;
+}
+
+// Mongoose Schema definition for the 'concepts' collection
+const ConceptSchema: Schema = new Schema({
+ name: { type: String, required: true, unique: true }, // 'name' should be unique
+ description: { type: String },
+ spotlight_fact: { type: String },
+ lecture: { type: String },
+}, { collection: 'concepts' }); // Explicitly link to the 'concepts' collection
+
+// Create or retrieve the Mongoose Model for 'Concept'
+const Concept = mongoose.models.Concept || mongoose.model('Concept', ConceptSchema);
+
+
+// --- Configuration for MongoDB Connection ---
+// Use environment variable MONGO_URI, or fallback to your hardcoded one
+const MONGO_URI = process.env.MONGO_URI || "mongodb+srv://akssrf2025:Aks1234@cluster0.oek3we1.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
+const DATABASE_NAME = process.env.DATABASE_NAME || "LearnFlowDB";
+
+let mongooseConnected = false; // Flag to track Mongoose connection status
+
+// --- Connect to MongoDB Function ---
+async function connectToMongoDB() {
+ try {
+ console.log(`DEBUG: spotlight_server.ts using MONGO_URI: ${MONGO_URI}`);
+ console.log(`DEBUG: spotlight_server.ts targeting DATABASE_NAME: ${DATABASE_NAME}`);
+ await mongoose.connect(MONGO_URI, {
+ dbName: DATABASE_NAME,
+ // useNewUrlParser and useUnifiedTopology are deprecated in Mongoose 6+ and can be safely removed
+ // from future Mongoose versions, but keeping for compatibility.
+ useNewUrlParser: true,
+ useUnifiedTopology: true,
+ } as mongoose.ConnectOptions);
+ mongooseConnected = true;
+ console.log("β
Mongoose Connected to MongoDB Atlas");
+
+ // Optional: Log collections in the connected DB (useful for verification)
+ if (mongoose.connection.db) {
+ const collectionsInDb = await mongoose.connection.db.listCollections().toArray();
+ console.log("INFO: Collections in connected DB:", collectionsInDb.map(c => c.name));
+ }
+
+ } catch (error) {
+ console.error("β ERROR: Failed to connect to MongoDB:", error);
+ process.exit(1); // Exit process if DB connection fails
+ }
+}
+
+// --- Health Check Endpoint ---
+// Provides a simple way to check if the server is running and connected to the DB
+app.get('/health', async (req: Request, res: Response) => {
+ const status: { [key: string]: string } = { "status": "OK", "database": "Disconnected" };
+ if (mongooseConnected) {
+ // Check Mongoose connection state (1 means connected, 0 disconnected, 2 connecting, 3 disconnecting)
+ if (mongoose.connection.readyState === 1) {
+ status["database"] = "Connected";
+ } else {
+ status["database"] = "Connecting/Disconnected";
+ }
+ } else {
+ status["status"] = "DEGRADED"; // If Mongoose never connected
+ }
+ res.json(status);
+});
+
+// --- API Endpoint: Get All Concept Names ---
+// Fetches and returns a list of all concept names from the database.
+// This is used to populate the dropdown on the frontend.
+app.get('/api/concepts/all', (async (req: Request, res: Response) => {
+ console.log("INFO: API request received for all concept names.");
+ if (!mongooseConnected) {
+ return res.status(503).json({ error: "Database not connected. Cannot fetch all concepts." });
+ }
+
+ try {
+ // Use Mongoose's find() method to get all documents
+ // .select('name -_id') projects only the 'name' field and excludes '_id'
+ // .lean() makes the result plain JavaScript objects, not Mongoose documents, for performance
+ const concepts = await Concept.find({}, 'name -_id').lean();
+ console.log("DEBUG: Raw concepts found by server:", concepts); // ADDED THIS DEBUG LOG
+
+ // Extract just the 'name' from each concept object and filter out any null/undefined names
+ const namesOnly = concepts.map(concept => concept.name).filter(Boolean) as string[];
+
+ console.log(`INFO: Found ${namesOnly.length} concept names.`);
+ res.json(namesOnly); // Send the array of names as JSON
+
+ } catch (error) {
+ console.error("β ERROR: Error fetching all concept names:", error);
+ res.status(500).json({ error: "Could not retrieve all concept names", details: error instanceof Error ? error.message : String(error) });
+ }
+}) as RequestHandler);
+
+
+// --- API Endpoint: Get Concept Spotlight by Name ---
+// Fetches and returns the spotlight fact for a specific concept name.
+app.get('/api/concept-spotlight/:conceptName', (async (req: Request, res: Response) => {
+ const conceptName = req.params.conceptName; // Get concept name from URL parameter
+
+ console.log(`INFO: API request received for concept: '${conceptName}'`);
+
+ if (!mongooseConnected) {
+ return res.status(503).json({ error: "Database not connected. Cannot fetch concept spotlight." });
+ }
+
+ try {
+ // Use Mongoose's findOne() to find a single concept by name (case-insensitive)
+ // new RegExp(`^${conceptName}$`, 'i') ensures exact, case-insensitive match
+ const conceptData: IConcept | null = await Concept.findOne({ name: new RegExp(`^${conceptName}$`, 'i') });
+
+ let fact = "No fun fact available for this concept yet!"; // Default message if not found or no fact
+
+ // Check if a concept was found AND if it has a valid spotlight_fact
+ if (conceptData && typeof conceptData.spotlight_fact === 'string' && conceptData.spotlight_fact.length > 0) {
+ fact = conceptData.spotlight_fact;
+ console.log(`INFO: Found spotlight fact for '${conceptName}'.`);
+ } else {
+ console.log(`INFO: No valid spotlight_fact found for concept: '${conceptName}'.`);
+ }
+
+ res.json({ concept: conceptName, fact: fact }); // Send the concept name and its fact
+
+ } catch (error) {
+ console.error(`β ERROR: Error fetching concept spotlight for ${conceptName}:`, error);
+ res.status(500).json({ error: "Could not retrieve concept spotlight", details: error instanceof Error ? error.message : String(error) });
+ }
+}) as RequestHandler);
+
+
+// --- Start the Server Function ---
+// Connects to MongoDB, then starts the Express server.
+async function startServer() {
+ await connectToMongoDB(); // Ensure database connection before starting to listen for requests
+ app.listen(port, () => {
+ console.log(`\n======================================================`);
+ console.log(`π’ Standalone Concept Spotlight Server is running!`);
+ console.log(`Β Β Local URL: http://localhost:${port}`);
+ console.log(`======================================================`);
+ console.log(`\nAPI Endpoints Ready:`);
+ console.log(`Β Β - Health Check:Β Β Β Β Β Β http://localhost:${port}/health`);
+ console.log(`Β Β - Get All Concepts:Β Β Β Β http://localhost:${port}/api/concepts/all`);
+ console.log(`Β Β - Get Concept Spotlight:Β http://localhost:${port}/api/concept-spotlight/Algorithms (or any other concept name)`);
+ console.log(`\n(Remember to use 'ts-node standalone_tests/spotlight_server.ts' to run this server)`);
+ });
+}
+
+// Call the function to start the server
+startServer();
\ No newline at end of file
diff --git a/server/tsconfig.json b/team-bhavitha-dsarecommender/server/tsconfig.json
similarity index 97%
rename from server/tsconfig.json
rename to team-bhavitha-dsarecommender/server/tsconfig.json
index bd713f8cb..208a7a238 100644
--- a/server/tsconfig.json
+++ b/team-bhavitha-dsarecommender/server/tsconfig.json
@@ -27,7 +27,8 @@
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
- // "rootDir": "./", /* Specify the root folder within your source files. */
+ "rootDir": "./src",
+ "outDir": "./dist", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
@@ -109,5 +110,14 @@
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
- }
+ },
+ "include": ["src/**/*"],
+ "exclude": [
+ "src/scripts",
+ "standalone_tests",
+ "types",
+ "node_modules",
+ "dist"
+]
+
}
diff --git a/team-bhavitha-dsarecommender/server/types/quiz.ts b/team-bhavitha-dsarecommender/server/types/quiz.ts
new file mode 100644
index 000000000..7c48edfa6
--- /dev/null
+++ b/team-bhavitha-dsarecommender/server/types/quiz.ts
@@ -0,0 +1,13 @@
+// server/types/quiz.ts
+
+export interface MCQQuestion {
+ question: string;
+ options: string[];
+ correctAnswer: string;
+}
+
+export interface QuizSubmission {
+ topic: string;
+ username: string;
+ answers: string[];
+}