+ {/* Kitchen Sink Example */}
+
+
+
+
+ Kitchen Sink Example
+
+
+
+ A comprehensive example showcasing multiple JSDoc features in one code block
+
+
+
+
+
+
+
+ {/* Navigation Grid */}
+
+
Explore JSDoc Sections
+
+ Choose a section to dive deeper into specific JSDoc features
+
-
-
- {/* Sidebar Navigation */}
-
-
- {/* Main Content */}
-
-
- {/* Kitchen Sink Example */}
-
-
-
-
- Kitchen Sink Example
-
-
-
- A comprehensive example showcasing multiple JSDoc features in one code block
-
-
-
-
-
-
-
- {/* Section Header */}
-
-
- {jsdocData[activeSection as keyof typeof jsdocData]?.title || "Section"}
-
-
- {jsdocData[activeSection as keyof typeof jsdocData]?.description || "Documentation section"}
-
-
-
- {/* Content Cards */}
-
- {jsdocData[activeSection as keyof typeof jsdocData]?.items.map((item, index) => (
-
-
-
-
-
- {item.tag}
-
-
+
+ {navigationSections.map((section) => {
+ const Icon = section.icon
+ return (
+
+
+
+
+
- {item.description}
+
+ {section.title}
+
+
+ {section.description}
+
-
- {/* Syntax */}
-
-
Syntax:
-
- {item.syntax}
-
-
-
-
-
- {/* Example with Syntax Highlighting */}
-
-
Example:
-
-
+
+
- )) || []}
+
+ )
+ })}
+
+
+ {/* Quick Reference */}
+
+
+
+
+ Quick Reference
+
+
+ Essential JSDoc tags you'll use most frequently
+
+
+
+
+
+
Basic Tags
+
+ @description
+ @author
+ @version
+ @since
+
+
+
+
Parameters
+
+ @param
+ @returns
+ @throws
+ @example
+
+
+
+
Types & Classes
+
+ @typedef
+ @class
+ @method
+ @static
+
+
+
+
Advanced
+
+ @module
+ @callback
+ @interface
+ @link
+
+
-
-
+
+
@@ -977,4 +230,4 @@ export default function JSDocCheatsheet() {
)
-}
+}
\ No newline at end of file
diff --git a/app/parameters/page.tsx b/app/parameters/page.tsx
new file mode 100644
index 0000000..d7be16e
--- /dev/null
+++ b/app/parameters/page.tsx
@@ -0,0 +1,103 @@
+"use client"
+
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { Badge } from "@/components/ui/badge"
+import { Separator } from "@/components/ui/separator"
+import { Code } from "lucide-react"
+import CodeHighlighter from "@/components/SyntaxHighlighter"
+import Sidebar from "@/components/Sidebar"
+import TableOfContents from "@/components/TableOfContents"
+import { jsdocData } from "@/lib/jsdoc-data"
+import Header from "@/components/Header"
+
+const parametersData = jsdocData.parameters
+
+export default function ParametersPage() {
+ // Generate TOC items from the data
+ const tocItems = parametersData.items.map((item, index) => ({
+ id: item.tag.replace("@", "").replace(/[^a-zA-Z0-9]/g, "-"),
+ title: item.tag,
+ level: 1
+ }))
+
+ return (
+
+
+
+
+
+
+
+ {/* Section Header */}
+
+
+ {parametersData.title}
+
+
+ {parametersData.description}
+
+
+
+ {/* Content Cards */}
+
+ {parametersData.items.map((item, index) => (
+
+
+
+
+
+ {item.tag}
+
+
+
+ {item.description}
+
+
+ {/* Syntax */}
+
+
Syntax:
+
+ {item.syntax}
+
+
+
+
+
+ {/* Example with Syntax Highlighting */}
+
+
Example:
+
+
+
+
+ ))}
+
+
+
+
+ {/* Footer */}
+
+
+ )
+}
diff --git a/app/type-definitions/page.tsx b/app/type-definitions/page.tsx
new file mode 100644
index 0000000..a38b9b6
--- /dev/null
+++ b/app/type-definitions/page.tsx
@@ -0,0 +1,102 @@
+"use client"
+
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { Badge } from "@/components/ui/badge"
+import { Separator } from "@/components/ui/separator"
+import CodeHighlighter from "@/components/SyntaxHighlighter"
+import Sidebar from "@/components/Sidebar"
+import TableOfContents from "@/components/TableOfContents"
+import { jsdocData } from "@/lib/jsdoc-data"
+import Header from "@/components/Header"
+
+const typeDefinitionsData = jsdocData.types
+
+export default function TypeDefinitionsPage() {
+ // Generate TOC items from the data
+ const tocItems = typeDefinitionsData.items.map((item, index) => ({
+ id: item.tag.replace("@", "").replace(/[^a-zA-Z0-9]/g, "-"),
+ title: item.tag,
+ level: 1
+ }))
+
+ return (
+
+
+
+
+
+
+
+ {/* Section Header */}
+
+
+ {typeDefinitionsData.title}
+
+
+ {typeDefinitionsData.description}
+
+
+
+ {/* Content Cards */}
+
+ {typeDefinitionsData.items.map((item, index) => (
+
+
+
+
+
+ {item.tag}
+
+
+
+ {item.description}
+
+
+ {/* Syntax */}
+
+
Syntax:
+
+ {item.syntax}
+
+
+
+
+
+ {/* Example with Syntax Highlighting */}
+
+
Example:
+
+
+
+
+ ))}
+
+
+
+
+ {/* Footer */}
+
+
+ )
+}
diff --git a/components/Content.tsx b/components/Content.tsx
new file mode 100644
index 0000000..1a636ae
--- /dev/null
+++ b/components/Content.tsx
@@ -0,0 +1,139 @@
+'use client'
+
+import React from 'react'
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { Badge } from "@/components/ui/badge"
+import { Separator } from "@/components/ui/separator"
+import CustomSyntaxHighlighter from "@/components/SyntaxHighlighter"
+import { ExternalLink } from "lucide-react"
+
+interface Source {
+ name: string
+ url: string
+ description: string
+}
+
+interface JSDocItem {
+ tag: string
+ syntax: string
+ example: string
+ description: string
+ sources?: Source[]
+}
+
+interface JSDocSection {
+ title: string
+ description: string
+ items: JSDocItem[]
+}
+
+interface ContentProps {
+ activeSection: string
+ jsdocData: Record
+}
+
+export default function Content({ activeSection, jsdocData }: ContentProps) {
+ const currentSection = jsdocData[activeSection]
+
+ return (
+
+
+ {/* Kitchen Sink Example */}
+ {activeSection === 'kitchen-sink' && (
+
+
+
+
+ Kitchen Sink Example
+
+
+
+ A comprehensive example showcasing multiple JSDoc features in one code block
+
+
+
+
+
+
+ )}
+
+ {/* Section Header */}
+
+
+ {currentSection?.title || "Section"}
+
+
+ {currentSection?.description || "Documentation section"}
+
+
+
+ {/* Content Cards */}
+
+ {currentSection?.items.map((item, index) => (
+
+
+
+
+
+ {item.tag}
+
+
+
+ {item.description}
+
+
+ {/* Syntax */}
+
+
Syntax:
+
+ {item.syntax}
+
+
+
+
+
+ {/* Example with Syntax Highlighting */}
+
+
Example:
+
+
+
+ {/* Source Links */}
+ {item.sources && item.sources.length > 0 && (
+ <>
+
+
+
Sources & References:
+
+ {item.sources.map((source, sourceIndex) => (
+
+ ))}
+
+
+ >
+ )}
+
+
+ )) || []}
+
+
+
+ )
+}
diff --git a/components/Header.tsx b/components/Header.tsx
new file mode 100644
index 0000000..49172d7
--- /dev/null
+++ b/components/Header.tsx
@@ -0,0 +1,19 @@
+"use client"
+
+import { BookOpen } from "lucide-react"
+import Link from "next/link"
+
+export default function Header() {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx
new file mode 100644
index 0000000..afd8305
--- /dev/null
+++ b/components/Sidebar.tsx
@@ -0,0 +1,87 @@
+"use client"
+
+import { Button } from "@/components/ui/button"
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import { Badge } from "@/components/ui/badge"
+import { BookOpen, Code, FileText, Hash, Settings, Tag, Info, Users, Navigation, ChevronRight, Home } from "lucide-react"
+import Link from "next/link"
+import { usePathname } from "next/navigation"
+
+const navigationItems = [
+ { name: "Kitchen Sink", href: "/", icon: Home },
+ { name: "Basic Tags", href: "/basic-tags", icon: Tag },
+ { name: "Parameters", href: "/parameters", icon: Code },
+ { name: "Types", href: "/type-definitions", icon: Hash },
+ { name: "Functions", href: "/functions", icon: Settings },
+ { name: "Modules", href: "/modules", icon: FileText },
+ { name: "Advanced", href: "/advanced", icon: BookOpen },
+ { name: "Objects", href: "/objects", icon: Hash },
+ { name: "Docs", href: "/documentation", icon: Info },
+ { name: "Examples", href: "/examples", icon: Info },
+ { name: "Best Practices", href: "/best-practices", icon: Users },
+]
+
+export default function Sidebar() {
+ const pathname = usePathname()
+
+ return (
+
+ )
+}
diff --git a/components/SyntaxHighlighter.tsx b/components/SyntaxHighlighter.tsx
new file mode 100644
index 0000000..983d4f6
--- /dev/null
+++ b/components/SyntaxHighlighter.tsx
@@ -0,0 +1,46 @@
+"use client"
+
+import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
+import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'
+
+interface SyntaxHighlighterProps {
+ code: string
+ language?: string
+}
+
+const CodeHighlighter = ({ code, language = "javascript" }: SyntaxHighlighterProps) => {
+ return (
+
+
(
+
+ {children}
+
+ )}
+ >
+ {code}
+
+
+ )
+}
+
+export default CodeHighlighter
\ No newline at end of file
diff --git a/components/TableOfContents.tsx b/components/TableOfContents.tsx
new file mode 100644
index 0000000..24a5ee8
--- /dev/null
+++ b/components/TableOfContents.tsx
@@ -0,0 +1,148 @@
+"use client"
+
+import { useState, useEffect } from "react"
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import { Button } from "@/components/ui/button"
+import { Badge } from "@/components/ui/badge"
+import { List, ChevronRight, Hash } from "lucide-react"
+
+interface TOCItem {
+ id: string
+ title: string
+ level: number
+}
+
+interface TableOfContentsProps {
+ items: TOCItem[]
+ className?: string
+}
+
+export default function TableOfContents({ items, className = "" }: TableOfContentsProps) {
+ const [activeId, setActiveId] = useState("")
+ const [isVisible, setIsVisible] = useState(false)
+
+ useEffect(() => {
+ if (items.length === 0) return
+
+ // Calculate header height dynamically
+ const header = document.querySelector('header')
+ const headerHeight = header ? header.offsetHeight + 20 : 100 // 20px buffer
+ const rootMargin = `-${headerHeight}px 0% -35% 0%`
+
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ setActiveId(entry.target.id)
+ }
+ })
+ },
+ {
+ rootMargin,
+ threshold: 0.1,
+ }
+ )
+
+ // Observe all TOC items
+ items.forEach((item) => {
+ const element = document.getElementById(item.id)
+ if (element) {
+ observer.observe(element)
+ }
+ })
+
+ return () => {
+ items.forEach((item) => {
+ const element = document.getElementById(item.id)
+ if (element) {
+ observer.unobserve(element)
+ }
+ })
+ }
+ }, [items])
+
+ useEffect(() => {
+ // Show TOC if there are items
+ setIsVisible(items.length > 0)
+ }, [items])
+
+ const scrollToSection = (id: string) => {
+ const element = document.getElementById(id)
+ if (element) {
+ // Get the actual header height dynamically
+ const header = document.querySelector('header')
+ const headerHeight = header ? header.offsetHeight + 20 : 100 // 20px buffer
+ const elementPosition = element.offsetTop - headerHeight
+
+ // Add a small delay to ensure smooth scrolling
+ setTimeout(() => {
+ window.scrollTo({
+ top: Math.max(0, elementPosition), // Ensure we don't scroll to negative position
+ behavior: "smooth"
+ })
+ }, 10)
+ }
+ }
+
+ if (!isVisible) return null
+
+ return (
+
+ )
+}
diff --git a/lib/data-loader.ts b/lib/data-loader.ts
new file mode 100644
index 0000000..32f5c84
--- /dev/null
+++ b/lib/data-loader.ts
@@ -0,0 +1,15 @@
+import { jsdocData } from '@/data/jsdoc-data'
+import { restoredJSDocData } from '@/data/restored-jsdoc-data'
+
+// Lazy load data for better performance
+export const loadSectionData = async (sectionId: string) => {
+ return jsdocData[sectionId] || jsdocData.basic
+}
+
+// Preload critical data - use restored data for now
+export const preloadCriticalData = async () => {
+ return {
+ ...jsdocData,
+ ...restoredJSDocData
+ }
+}
diff --git a/lib/jsdoc-data.ts b/lib/jsdoc-data.ts
new file mode 100644
index 0000000..e572a53
--- /dev/null
+++ b/lib/jsdoc-data.ts
@@ -0,0 +1,632 @@
+export const jsdocData = {
+ kitchenSink: {
+ title: "Kitchen Sink Example",
+ description: "A comprehensive example showcasing multiple JSDoc features in one code block",
+ items: [
+ {
+ tag: "Complete Example",
+ syntax: "Complete function documentation",
+ example: `/**
+ * Advanced user management service with comprehensive JSDoc documentation
+ * @module UserService
+ * @description Handles user creation, authentication, and profile management
+ * @author Jane Smith
+ * @version 2.1.0
+ * @since 1.0.0
+ * @requires Database
+ * @requires EmailService
+ * @exports UserService
+ * @example
+ * // Initialize the service
+ * const userService = new UserService(database, emailService);
+ *
+ * // Create a new user
+ * const user = await userService.createUser({
+ * name: 'John Doe',
+ * email: 'john@example.com',
+ * role: 'admin'
+ * });
+ */
+
+/**
+ * @typedef {Object} UserData
+ * @property {string} name - Full name of the user
+ * @property {string} email - Email address (must be unique)
+ * @property {('admin'|'user'|'guest')} [role='user'] - User role in the system
+ * @property {number} [age] - User age (optional)
+ * @property {UserPreferences} [preferences] - User preferences object
+ */
+
+/**
+ * @typedef {Object} UserPreferences
+ * @property {boolean} emailNotifications - Whether to send email notifications
+ * @property {string} theme - UI theme preference
+ * @property {string} language - Preferred language code
+ */
+
+/**
+ * @callback ValidationCallback
+ * @param {Error|null} error - Validation error if any
+ * @param {boolean} isValid - Whether the data is valid
+ */
+
+/**
+ * User management service class
+ * @class UserService
+ * @implements {EventEmitter}
+ * @fires UserService#userCreated
+ * @fires UserService#userDeleted
+ * @example
+ * const service = new UserService(db, emailService);
+ * service.on('userCreated', (user) => {
+ * console.log('New user created:', user.name);
+ * });
+ */
+class UserService extends EventEmitter {
+ /**
+ * Creates a new UserService instance
+ * @constructor
+ * @param {Database} database - Database connection instance
+ * @param {EmailService} emailService - Email service for notifications
+ * @throws {TypeError} When database or emailService is not provided
+ * @since 1.0.0
+ */
+ constructor(database, emailService) {
+ super();
+ if (!database || !emailService) {
+ throw new TypeError('Database and EmailService are required');
+ }
+ this.db = database;
+ this.emailService = emailService;
+ }
+
+ /**
+ * Creates a new user in the system
+ * @async
+ * @method createUser
+ * @memberof UserService
+ * @param {UserData} userData - User information object
+ * @param {Object} [options={}] - Additional options
+ * @param {boolean} [options.sendWelcomeEmail=true] - Send welcome email
+ * @param {boolean} [options.validateEmail=true] - Validate email format
+ * @returns {Promise} Promise resolving to created user object
+ * @throws {ValidationError} When user data is invalid
+ * @throws {DuplicateEmailError} When email already exists
+ * @throws {DatabaseError} When database operation fails
+ * @fires UserService#userCreated
+ * @example
+ * // Basic user creation
+ * const user = await userService.createUser({
+ * name: 'Alice Johnson',
+ * email: 'alice@example.com'
+ * });
+ *
+ * @example
+ * // Advanced user creation with options
+ * const adminUser = await userService.createUser({
+ * name: 'Bob Admin',
+ * email: 'bob@example.com',
+ * role: 'admin',
+ * preferences: {
+ * emailNotifications: false,
+ * theme: 'dark',
+ * language: 'en'
+ * }
+ * }, {
+ * sendWelcomeEmail: false,
+ * validateEmail: true
+ * });
+ * @since 1.0.0
+ * @todo Add support for bulk user creation
+ * @todo Implement user avatar upload
+ */
+ async createUser(userData, options = {}) {
+ // Implementation here...
+
+ /**
+ * User created event
+ * @event UserService#userCreated
+ * @type {Object}
+ * @property {User} user - The created user object
+ * @property {Date} timestamp - When the user was created
+ */
+ this.emit('userCreated', { user: newUser, timestamp: new Date() });
+
+ return newUser;
+ }
+
+ /**
+ * Validates user email address
+ * @static
+ * @method validateEmail
+ * @param {string} email - Email address to validate
+ * @param {ValidationCallback} callback - Callback function for validation result
+ * @returns {boolean} True if email format is valid
+ * @example
+ * // Synchronous validation
+ * const isValid = UserService.validateEmail('test@example.com');
+ *
+ * // Asynchronous validation with callback
+ * UserService.validateEmail('test@example.com', (error, isValid) => {
+ * if (error) {
+ * console.error('Validation error:', error);
+ * } else {
+ * console.log('Email is valid:', isValid);
+ * }
+ * });
+ * @since 1.2.0
+ */
+ static validateEmail(email, callback) {
+ // Implementation here...
+ }
+
+ /**
+ * @deprecated Since version 2.0.0. Use {@link UserService#createUser} instead.
+ * @method addUser
+ * @param {UserData} userData - User data
+ * @returns {Promise} Created user
+ * @see {@link UserService#createUser}
+ */
+ async addUser(userData) {
+ console.warn('addUser is deprecated. Use createUser instead.');
+ return this.createUser(userData);
+ }
+}
+
+/**
+ * @namespace UserService.Utils
+ * @description Utility functions for user management
+ */
+UserService.Utils = {
+ /**
+ * Formats user display name
+ * @function formatDisplayName
+ * @memberof UserService.Utils
+ * @param {string} firstName - User's first name
+ * @param {string} lastName - User's last name
+ * @returns {string} Formatted display name
+ * @example
+ * const displayName = UserService.Utils.formatDisplayName('John', 'Doe');
+ * console.log(displayName); // "John D."
+ */
+ formatDisplayName(firstName, lastName) {
+ return \`\${firstName} \${lastName.charAt(0)}.\`;
+ }
+};
+
+module.exports = UserService;`,
+ description: "Complete function documentation with all common tags",
+ },
+ ],
+ },
+ basic: {
+ title: "Basic Tags",
+ description: "Essential JSDoc tags for documenting your code",
+ items: [
+ {
+ tag: "@description",
+ syntax: "@description {string} Description text",
+ example:
+ "/**\n * @description Calculates the sum of two numbers\n * @param {number} a - First number\n * @param {number} b - Second number\n * @returns {number} The sum\n */\nfunction add(a, b) {\n return a + b;\n}",
+ description: "Provides a description of the function, class, or variable",
+ },
+ {
+ tag: "@author",
+ syntax: "@author {string} Author name ",
+ example: "/**\n * @author John Doe \n * @author Jane Smith \n */",
+ description: "Specifies the author(s) of the code",
+ },
+ {
+ tag: "@version",
+ syntax: "@version {string} Version number",
+ example: "/**\n * @version 1.2.0\n * @since 1.0.0\n */",
+ description: "Indicates the current version of the code",
+ },
+ {
+ tag: "@since",
+ syntax: "@since {string} Version when added",
+ example: "/**\n * @since 1.0.0\n * @description Added in the initial release\n */",
+ description: "Specifies when the feature was first added",
+ },
+ {
+ tag: "@deprecated",
+ syntax: "@deprecated {string} Deprecation message",
+ example:
+ "/**\n * @deprecated Since version 2.0.0. Use newFunction() instead.\n * @see {@link newFunction}\n */\nfunction oldFunction() {\n // deprecated implementation\n}",
+ description: "Marks code as deprecated with migration guidance",
+ },
+ ],
+ },
+ parameters: {
+ title: "Parameters & Returns",
+ description: "Document function parameters, return values, and exceptions",
+ items: [
+ {
+ tag: "@param",
+ syntax: "@param {type} name Description",
+ example:
+ "/**\n * @param {number} x - The first number\n * @param {number} y - The second number\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.strict=false] - Use strict mode\n */\nfunction calculate(x, y, options = {}) {\n // implementation\n}",
+ description: "Documents function parameters with types and descriptions",
+ },
+ {
+ tag: "@returns",
+ syntax: "@returns {type} Description",
+ example:
+ "/**\n * @param {number[]} numbers - Array of numbers\n * @returns {number} The sum of all numbers\n * @returns {null} Returns null if array is empty\n */\nfunction sum(numbers) {\n if (numbers.length === 0) return null;\n return numbers.reduce((a, b) => a + b, 0);\n}",
+ description: "Documents the return value and its type",
+ },
+ {
+ tag: "@throws",
+ syntax: "@throws {ErrorType} Description",
+ example:
+ "/**\n * @param {string} email - User email address\n * @throws {TypeError} When email is not a string\n * @throws {Error} When email format is invalid\n */\nfunction validateEmail(email) {\n if (typeof email !== 'string') {\n throw new TypeError('Email must be a string');\n }\n if (!email.includes('@')) {\n throw new Error('Invalid email format');\n }\n}",
+ description: "Documents exceptions that may be thrown",
+ },
+ {
+ tag: "@yields",
+ syntax: "@yields {type} Description",
+ example:
+ "/**\n * @generator\n * @yields {number} The next number in the Fibonacci sequence\n * @returns {Generator}\n */\nfunction* fibonacci() {\n let a = 0, b = 1;\n while (true) {\n yield a;\n [a, b] = [b, a + b];\n }\n}",
+ description: "Documents what a generator function yields",
+ },
+ ],
+ },
+ types: {
+ title: "Type Definitions",
+ description: "Define and document custom types and interfaces",
+ items: [
+ {
+ tag: "@typedef",
+ syntax: "@typedef {Object} TypeName",
+ example: "/**\n * @typedef {Object} User\n * @property {string} name\n * @property {number} age\n */",
+ description: "Defines a custom type",
+ },
+ {
+ tag: "@property",
+ syntax: "@property {type} name Description",
+ example: "/**\n * @property {string} email - User email address\n */",
+ description: "Documents object properties",
+ },
+ {
+ tag: "@enum",
+ syntax: "@enum {type}",
+ example: '/**\n * @enum {string}\n */\nconst Status = {\n PENDING: "pending",\n COMPLETE: "complete"\n}',
+ description: "Documents enumeration values",
+ },
+ {
+ tag: "@type",
+ syntax: "@type {type}",
+ example: "/**\n * @type {string|number}\n */\nlet value;",
+ description: "Specifies the type of a variable",
+ },
+ ],
+ },
+ functions: {
+ title: "Functions & Classes",
+ description: "Document functions, classes, constructors, and methods",
+ items: [
+ {
+ tag: "@function",
+ syntax: "@function",
+ example: "/**\n * @function calculateTotal\n * @description Calculates order total\n */",
+ description: "Explicitly marks something as a function",
+ },
+ {
+ tag: "@class",
+ syntax: "@class",
+ example: "/**\n * @class\n * @description Represents a user account\n */",
+ description: "Documents a class",
+ },
+ {
+ tag: "@constructor",
+ syntax: "@constructor",
+ example: "/**\n * @constructor\n * @param {string} name - User name\n */",
+ description: "Documents a constructor function",
+ },
+ {
+ tag: "@method",
+ syntax: "@method",
+ example: "/**\n * @method getName\n * @returns {string} The user name\n */",
+ description: "Documents a method",
+ },
+ {
+ tag: "@static",
+ syntax: "@static",
+ example: "/**\n * @static\n * @method createUser\n */",
+ description: "Indicates a static method or property",
+ },
+ {
+ tag: "@override",
+ syntax: "@override",
+ example: "/**\n * @override\n * @method toString\n */",
+ description: "Indicates method overrides parent method",
+ },
+ ],
+ },
+ modules: {
+ title: "Modules & Namespaces",
+ description: "Organize code with modules, namespaces, and membership",
+ items: [
+ {
+ tag: "@module",
+ syntax: "@module ModuleName",
+ example: "/**\n * @module UserUtils\n * @description Utilities for user management\n */",
+ description: "Documents a module",
+ },
+ {
+ tag: "@namespace",
+ syntax: "@namespace NamespaceName",
+ example: "/**\n * @namespace MyApp.Utils\n */",
+ description: "Documents a namespace",
+ },
+ {
+ tag: "@memberof",
+ syntax: "@memberof ParentName",
+ example: "/**\n * @memberof MyApp.Utils\n * @function formatName\n */",
+ description: "Indicates membership in a parent",
+ },
+ {
+ tag: "@exports",
+ syntax: "@exports ModuleName",
+ example: "/**\n * @exports UserService\n */",
+ description: "Documents what a module exports",
+ },
+ {
+ tag: "@requires",
+ syntax: "@requires ModuleName",
+ example: "/**\n * @requires lodash\n */",
+ description: "Documents module dependencies",
+ },
+ ],
+ },
+ advanced: {
+ title: "Advanced Tags",
+ description: "Advanced JSDoc features for complex documentation needs",
+ items: [
+ {
+ tag: "@callback",
+ syntax: "@callback CallbackName",
+ example: "/**\n * @callback RequestCallback\n * @param {Error} error\n * @param {Object} response\n */",
+ description: "Documents a callback function type",
+ },
+ {
+ tag: "@event",
+ syntax: "@event EventName",
+ example: "/**\n * @event MyClass#dataLoaded\n * @type {Object}\n */",
+ description: "Documents an event",
+ },
+ {
+ tag: "@fires",
+ syntax: "@fires EventName",
+ example: "/**\n * @fires MyClass#dataLoaded\n */",
+ description: "Indicates function fires an event",
+ },
+ {
+ tag: "@listens",
+ syntax: "@listens EventName",
+ example: "/**\n * @listens MyClass#dataLoaded\n */",
+ description: "Indicates function listens to an event",
+ },
+ {
+ tag: "@mixes",
+ syntax: "@mixes MixinName",
+ example: "/**\n * @mixes EventEmitter\n */",
+ description: "Documents that class mixes in another",
+ },
+ {
+ tag: "@abstract",
+ syntax: "@abstract",
+ example: "/**\n * @abstract\n * @method process\n */",
+ description: "Indicates abstract method or class",
+ },
+ ],
+ },
+ objects: {
+ title: "Objects & Interfaces",
+ description: "Document object structures, interfaces, and inheritance",
+ items: [
+ {
+ tag: "@interface",
+ syntax: "@interface InterfaceName",
+ example: "/**\n * @interface Drawable\n * @description Interface for drawable objects\n */",
+ description: "Documents an interface that classes can implement",
+ },
+ {
+ tag: "@implements",
+ syntax: "@implements {InterfaceName}",
+ example: "/**\n * @class Circle\n * @implements {Drawable}\n */",
+ description: "Indicates that a class implements an interface",
+ },
+ {
+ tag: "@extends",
+ syntax: "@extends ParentClass",
+ example: "/**\n * @class ColoredCircle\n * @extends Circle\n */",
+ description: "Documents class inheritance",
+ },
+ {
+ tag: "@mixin",
+ syntax: "@mixin MixinName",
+ example: "/**\n * @mixin EventEmitter\n * @description Adds event handling capabilities\n */",
+ description: "Documents a mixin that can be mixed into classes",
+ },
+ ],
+ },
+ documentation: {
+ title: "Documentation Tags",
+ description: "Tags for linking, examples, and additional documentation",
+ items: [
+ {
+ tag: "@example",
+ syntax: "@example\n// Example code here",
+ example:
+ "/**\n * @example\n * // Basic usage\n * const result = myFunction('test');\n * console.log(result);\n */",
+ description: "Provides usage examples",
+ },
+ {
+ tag: "@see",
+ syntax: "@see {reference}",
+ example: "/**\n * @see {@link MyClass#method}\n * @see https://example.com/docs\n */",
+ description: "References related documentation or code",
+ },
+ {
+ tag: "@link",
+ syntax: "{@link reference}",
+ example: "/**\n * Uses {@link MyClass} for processing\n */",
+ description: "Creates inline links to other documentation",
+ },
+ {
+ tag: "@tutorial",
+ syntax: "@tutorial TutorialName",
+ example: "/**\n * @tutorial getting-started\n */",
+ description: "Links to a tutorial document",
+ },
+ {
+ tag: "@todo",
+ syntax: "@todo Description of what needs to be done",
+ example: "/**\n * @todo Add input validation\n * @todo Optimize performance\n */",
+ description: "Documents future improvements or fixes needed",
+ },
+ ],
+ },
+ examples: {
+ title: "Complete Examples",
+ description: "Real-world JSDoc documentation examples",
+ items: [
+ {
+ tag: "Function Example",
+ syntax: "Complete function documentation",
+ example: `/**
+ * Calculates the area of a rectangle
+ * @function calculateArea
+ * @param {number} width - The width of the rectangle
+ * @param {number} height - The height of the rectangle
+ * @returns {number} The area of the rectangle
+ * @throws {TypeError} When width or height is not a number
+ * @example
+ * // Calculate area of 5x3 rectangle
+ * const area = calculateArea(5, 3);
+ * console.log(area); // 15
+ * @since 1.0.0
+ * @author Jane Smith
+ */
+function calculateArea(width, height) {
+ if (typeof width !== 'number' || typeof height !== 'number') {
+ throw new TypeError('Width and height must be numbers');
+ }
+ return width * height;
+}`,
+ description: "Complete function documentation with all common tags",
+ },
+ {
+ tag: "Class Example",
+ syntax: "Complete class documentation",
+ example: `/**
+ * Represents a user in the system
+ * @class User
+ * @param {string} name - The user's name
+ * @param {string} email - The user's email address
+ * @example
+ * const user = new User('John Doe', 'john@example.com');
+ * console.log(user.getName()); // 'John Doe'
+ */
+class User {
+ /**
+ * Create a user
+ * @constructor
+ * @param {string} name - The user's name
+ * @param {string} email - The user's email address
+ */
+ constructor(name, email) {
+ this.name = name;
+ this.email = email;
+ }
+
+ /**
+ * Get the user's name
+ * @method getName
+ * @returns {string} The user's name
+ */
+ getName() {
+ return this.name;
+ }
+}`,
+ description: "Complete class documentation with constructor and methods",
+ },
+ {
+ tag: "Module Example",
+ syntax: "Complete module documentation",
+ example: `/**
+ * User management module
+ * @module UserManagement
+ * @description Handles user creation and deletion
+ * @requires Database
+ * @requires EmailService
+ * @exports createUser
+ * @exports deleteUser
+ * @example
+ * // Create a user
+ * const user = createUser('John Doe', 'john@example.com');
+ * console.log(user);
+ *
+ * // Delete a user
+ * deleteUser(user.id);
+ */
+const Database = require('./Database');
+const EmailService = require('./EmailService');
+
+function createUser(name, email) {
+ // Implementation here
+}
+
+function deleteUser(userId) {
+ // Implementation here
+}
+
+module.exports = {
+ createUser,
+ deleteUser
+};`,
+ description: "Complete module documentation with dependencies and exports",
+ },
+ ],
+ },
+ "best-practices": {
+ title: "Best Practices",
+ description: "Guidelines for writing effective JSDoc documentation",
+ items: [
+ {
+ tag: "Consistency",
+ syntax: "Use consistent formatting and style",
+ example:
+ "// Always use the same format for similar tags\n// Good: @param {string} name - User name\n// Good: @param {number} age - User age",
+ description: "Maintain consistent formatting across your documentation",
+ },
+ {
+ tag: "Completeness",
+ syntax: "Document all public APIs",
+ example: "// Document all parameters, return values, and exceptions\n// Include examples for complex functions",
+ description: "Ensure all public functions, classes, and modules are documented",
+ },
+ {
+ tag: "Clarity",
+ syntax: "Write clear, concise descriptions",
+ example: "// Good: Calculates user age from birth date\n// Bad: Does age stuff",
+ description: "Use clear, descriptive language that explains purpose and behavior",
+ },
+ {
+ tag: "Type Safety",
+ syntax: "Always specify types for parameters and returns",
+ example:
+ "// Always include types\n@param {string|null} name - User name or null\n@returns {Promise} Promise resolving to user object",
+ description: "Include detailed type information to improve code reliability",
+ },
+ {
+ tag: "Examples",
+ syntax: "Include usage examples for complex functions",
+ example:
+ "/**\n * @example\n * // Basic usage\n * const result = myFunction('input');\n * \n * @example\n * // Advanced usage\n * const result = myFunction('input', { option: true });\n */",
+ description: "Provide practical examples showing how to use the code",
+ },
+ ],
+ },
+}
diff --git a/original-page.tsx b/original-page.tsx
new file mode 100644
index 0000000..f43db3d
--- /dev/null
+++ b/original-page.tsx
@@ -0,0 +1,980 @@
+"use client"
+
+import { useState, useEffect } from "react"
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import { ScrollArea } from "@/components/ui/scroll-area"
+import { Separator } from "@/components/ui/separator"
+import { BookOpen, Code, FileText, Hash, Info, Settings, Tag, Users, ChevronRight } from "lucide-react"
+
+const SyntaxHighlighter = ({ code, language = "javascript" }: { code: string; language?: string }) => {
+ const highlightCode = (text: string) => {
+ // Escape HTML first
+ let highlighted = text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """)
+
+ // Apply syntax highlighting with proper HTML structure
+ highlighted = highlighted
+ // JSDoc comments and tags
+ .replace(/(\/\*\*[\s\S]*?\*\/)/g, '$1')
+ .replace(/(@\w+)/g, '$1')
+
+ // JavaScript keywords
+ .replace(
+ /\b(function|class|const|let|var|if|else|for|while|return|async|await|new|this|super|extends|implements|static|public|private|protected)\b/g,
+ '$1',
+ )
+
+ // Strings
+ .replace(/(["'`])((?:\\.|(?!\1)[^\\])*?)\1/g, '$1$2$1')
+
+ // Numbers
+ .replace(/\b(\d+\.?\d*)\b/g, '$1')
+
+ // Booleans and null/undefined
+ .replace(/\b(true|false|null|undefined)\b/g, '$1')
+
+ // Types in curly braces
+ .replace(/\{([^}]+)\}/g, '{$1}')
+
+ return highlighted
+ }
+
+ return (
+
+
+
+ )
+}
+
+const sections = [
+ {
+ id: "kitchen-sink",
+ title: "Kitchen Sink Example",
+ icon: BookOpen,
+ subsections: ["Complete Example"],
+ },
+ {
+ id: "basic",
+ title: "Basic Tags",
+ icon: Tag,
+ subsections: ["@description", "@author", "@version", "@since", "@deprecated"],
+ },
+ {
+ id: "parameters",
+ title: "Parameters & Returns",
+ icon: Code,
+ subsections: ["@param", "@returns", "@throws", "@yields"],
+ },
+ {
+ id: "types",
+ title: "Type Definitions",
+ icon: Hash,
+ subsections: ["@typedef", "@property", "@enum", "@type"],
+ },
+ {
+ id: "functions",
+ title: "Functions & Classes",
+ icon: Settings,
+ subsections: ["@function", "@class", "@constructor", "@method", "@static", "@override"],
+ },
+ {
+ id: "modules",
+ title: "Modules & Namespaces",
+ icon: FileText,
+ subsections: ["@module", "@namespace", "@memberof", "@exports", "@requires"],
+ },
+ {
+ id: "advanced",
+ title: "Advanced Tags",
+ icon: BookOpen,
+ subsections: ["@callback", "@event", "@fires", "@listens", "@mixes", "@abstract"],
+ },
+ {
+ id: "objects",
+ title: "Objects & Interfaces",
+ icon: Hash,
+ subsections: ["@interface", "@implements", "@extends", "@mixin"],
+ },
+ {
+ id: "documentation",
+ title: "Documentation Tags",
+ icon: Info,
+ subsections: ["@example", "@see", "@link", "@tutorial", "@todo"],
+ },
+ {
+ id: "examples",
+ title: "Complete Examples",
+ icon: Info,
+ subsections: ["Function Example", "Class Example", "Module Example"],
+ },
+ {
+ id: "best-practices",
+ title: "Best Practices",
+ icon: Users,
+ subsections: ["Consistency", "Completeness", "Clarity", "Type Safety", "Examples"],
+ },
+]
+
+const jsdocData = {
+ kitchenSink: {
+ title: "Kitchen Sink Example",
+ description: "A comprehensive example showcasing multiple JSDoc features in one code block",
+ items: [
+ {
+ tag: "Complete Example",
+ syntax: "Complete function documentation",
+ example: `/**
+ * Advanced user management service with comprehensive JSDoc documentation
+ * @module UserService
+ * @description Handles user creation, authentication, and profile management
+ * @author Jane Smith
+ * @version 2.1.0
+ * @since 1.0.0
+ * @requires Database
+ * @requires EmailService
+ * @exports UserService
+ * @example
+ * // Initialize the service
+ * const userService = new UserService(database, emailService);
+ *
+ * // Create a new user
+ * const user = await userService.createUser({
+ * name: 'John Doe',
+ * email: 'john@example.com',
+ * role: 'admin'
+ * });
+ */
+
+/**
+ * @typedef {Object} UserData
+ * @property {string} name - Full name of the user
+ * @property {string} email - Email address (must be unique)
+ * @property {('admin'|'user'|'guest')} [role='user'] - User role in the system
+ * @property {number} [age] - User age (optional)
+ * @property {UserPreferences} [preferences] - User preferences object
+ */
+
+/**
+ * @typedef {Object} UserPreferences
+ * @property {boolean} emailNotifications - Whether to send email notifications
+ * @property {string} theme - UI theme preference
+ * @property {string} language - Preferred language code
+ */
+
+/**
+ * @callback ValidationCallback
+ * @param {Error|null} error - Validation error if any
+ * @param {boolean} isValid - Whether the data is valid
+ */
+
+/**
+ * User management service class
+ * @class UserService
+ * @implements {EventEmitter}
+ * @fires UserService#userCreated
+ * @fires UserService#userDeleted
+ * @example
+ * const service = new UserService(db, emailService);
+ * service.on('userCreated', (user) => {
+ * console.log('New user created:', user.name);
+ * });
+ */
+class UserService extends EventEmitter {
+ /**
+ * Creates a new UserService instance
+ * @constructor
+ * @param {Database} database - Database connection instance
+ * @param {EmailService} emailService - Email service for notifications
+ * @throws {TypeError} When database or emailService is not provided
+ * @since 1.0.0
+ */
+ constructor(database, emailService) {
+ super();
+ if (!database || !emailService) {
+ throw new TypeError('Database and EmailService are required');
+ }
+ this.db = database;
+ this.emailService = emailService;
+ }
+
+ /**
+ * Creates a new user in the system
+ * @async
+ * @method createUser
+ * @memberof UserService
+ * @param {UserData} userData - User information object
+ * @param {Object} [options={}] - Additional options
+ * @param {boolean} [options.sendWelcomeEmail=true] - Send welcome email
+ * @param {boolean} [options.validateEmail=true] - Validate email format
+ * @returns {Promise} Promise resolving to created user object
+ * @throws {ValidationError} When user data is invalid
+ * @throws {DuplicateEmailError} When email already exists
+ * @throws {DatabaseError} When database operation fails
+ * @fires UserService#userCreated
+ * @example
+ * // Basic user creation
+ * const user = await userService.createUser({
+ * name: 'Alice Johnson',
+ * email: 'alice@example.com'
+ * });
+ *
+ * @example
+ * // Advanced user creation with options
+ * const adminUser = await userService.createUser({
+ * name: 'Bob Admin',
+ * email: 'bob@example.com',
+ * role: 'admin',
+ * preferences: {
+ * emailNotifications: false,
+ * theme: 'dark',
+ * language: 'en'
+ * }
+ * }, {
+ * sendWelcomeEmail: false,
+ * validateEmail: true
+ * });
+ * @since 1.0.0
+ * @todo Add support for bulk user creation
+ * @todo Implement user avatar upload
+ */
+ async createUser(userData, options = {}) {
+ // Implementation here...
+
+ /**
+ * User created event
+ * @event UserService#userCreated
+ * @type {Object}
+ * @property {User} user - The created user object
+ * @property {Date} timestamp - When the user was created
+ */
+ this.emit('userCreated', { user: newUser, timestamp: new Date() });
+
+ return newUser;
+ }
+
+ /**
+ * Validates user email address
+ * @static
+ * @method validateEmail
+ * @param {string} email - Email address to validate
+ * @param {ValidationCallback} callback - Callback function for validation result
+ * @returns {boolean} True if email format is valid
+ * @example
+ * // Synchronous validation
+ * const isValid = UserService.validateEmail('test@example.com');
+ *
+ * // Asynchronous validation with callback
+ * UserService.validateEmail('test@example.com', (error, isValid) => {
+ * if (error) {
+ * console.error('Validation error:', error);
+ * } else {
+ * console.log('Email is valid:', isValid);
+ * }
+ * });
+ * @since 1.2.0
+ */
+ static validateEmail(email, callback) {
+ // Implementation here...
+ }
+
+ /**
+ * @deprecated Since version 2.0.0. Use {@link UserService#createUser} instead.
+ * @method addUser
+ * @param {UserData} userData - User data
+ * @returns {Promise} Created user
+ * @see {@link UserService#createUser}
+ */
+ async addUser(userData) {
+ console.warn('addUser is deprecated. Use createUser instead.');
+ return this.createUser(userData);
+ }
+}
+
+/**
+ * @namespace UserService.Utils
+ * @description Utility functions for user management
+ */
+UserService.Utils = {
+ /**
+ * Formats user display name
+ * @function formatDisplayName
+ * @memberof UserService.Utils
+ * @param {string} firstName - User's first name
+ * @param {string} lastName - User's last name
+ * @returns {string} Formatted display name
+ * @example
+ * const displayName = UserService.Utils.formatDisplayName('John', 'Doe');
+ * console.log(displayName); // "John D."
+ */
+ formatDisplayName(firstName, lastName) {
+ return \`\${firstName} \${lastName.charAt(0)}.\`;
+ }
+};
+
+module.exports = UserService;`,
+ description: "Complete function documentation with all common tags",
+ },
+ ],
+ },
+ basic: {
+ title: "Basic Tags",
+ description: "Essential JSDoc tags for documenting your code",
+ items: [
+ {
+ tag: "@description",
+ syntax: "@description {string} Description text",
+ example:
+ "/**\n * @description Calculates the sum of two numbers\n * @param {number} a - First number\n * @param {number} b - Second number\n * @returns {number} The sum\n */\nfunction add(a, b) {\n return a + b;\n}",
+ description: "Provides a description of the function, class, or variable",
+ },
+ {
+ tag: "@author",
+ syntax: "@author {string} Author name ",
+ example: "/**\n * @author John Doe \n * @author Jane Smith \n */",
+ description: "Specifies the author(s) of the code",
+ },
+ {
+ tag: "@version",
+ syntax: "@version {string} Version number",
+ example: "/**\n * @version 1.2.0\n * @since 1.0.0\n */",
+ description: "Indicates the current version of the code",
+ },
+ {
+ tag: "@since",
+ syntax: "@since {string} Version when added",
+ example: "/**\n * @since 1.0.0\n * @description Added in the initial release\n */",
+ description: "Specifies when the feature was first added",
+ },
+ {
+ tag: "@deprecated",
+ syntax: "@deprecated {string} Deprecation message",
+ example:
+ "/**\n * @deprecated Since version 2.0.0. Use newFunction() instead.\n * @see {@link newFunction}\n */\nfunction oldFunction() {\n // deprecated implementation\n}",
+ description: "Marks code as deprecated with migration guidance",
+ },
+ ],
+ },
+ parameters: {
+ title: "Parameters & Returns",
+ description: "Document function parameters, return values, and exceptions",
+ items: [
+ {
+ tag: "@param",
+ syntax: "@param {type} name Description",
+ example:
+ "/**\n * @param {number} x - The first number\n * @param {number} y - The second number\n * @param {Object} [options] - Optional configuration\n * @param {boolean} [options.strict=false] - Use strict mode\n */\nfunction calculate(x, y, options = {}) {\n // implementation\n}",
+ description: "Documents function parameters with types and descriptions",
+ },
+ {
+ tag: "@returns",
+ syntax: "@returns {type} Description",
+ example:
+ "/**\n * @param {number[]} numbers - Array of numbers\n * @returns {number} The sum of all numbers\n * @returns {null} Returns null if array is empty\n */\nfunction sum(numbers) {\n if (numbers.length === 0) return null;\n return numbers.reduce((a, b) => a + b, 0);\n}",
+ description: "Documents the return value and its type",
+ },
+ {
+ tag: "@throws",
+ syntax: "@throws {ErrorType} Description",
+ example:
+ "/**\n * @param {string} email - User email address\n * @throws {TypeError} When email is not a string\n * @throws {Error} When email format is invalid\n */\nfunction validateEmail(email) {\n if (typeof email !== 'string') {\n throw new TypeError('Email must be a string');\n }\n if (!email.includes('@')) {\n throw new Error('Invalid email format');\n }\n}",
+ description: "Documents exceptions that may be thrown",
+ },
+ {
+ tag: "@yields",
+ syntax: "@yields {type} Description",
+ example:
+ "/**\n * @generator\n * @yields {number} The next number in the Fibonacci sequence\n * @returns {Generator}\n */\nfunction* fibonacci() {\n let a = 0, b = 1;\n while (true) {\n yield a;\n [a, b] = [b, a + b];\n }\n}",
+ description: "Documents what a generator function yields",
+ },
+ ],
+ },
+ types: {
+ title: "Type Definitions",
+ description: "Define and document custom types and interfaces",
+ items: [
+ {
+ tag: "@typedef",
+ syntax: "@typedef {Object} TypeName",
+ example: "/**\n * @typedef {Object} User\n * @property {string} name\n * @property {number} age\n */",
+ description: "Defines a custom type",
+ },
+ {
+ tag: "@property",
+ syntax: "@property {type} name Description",
+ example: "/**\n * @property {string} email - User email address\n */",
+ description: "Documents object properties",
+ },
+ {
+ tag: "@enum",
+ syntax: "@enum {type}",
+ example: '/**\n * @enum {string}\n */\nconst Status = {\n PENDING: "pending",\n COMPLETE: "complete"\n}',
+ description: "Documents enumeration values",
+ },
+ {
+ tag: "@type",
+ syntax: "@type {type}",
+ example: "/**\n * @type {string|number}\n */\nlet value;",
+ description: "Specifies the type of a variable",
+ },
+ ],
+ },
+ functions: {
+ title: "Functions & Classes",
+ description: "Document functions, classes, constructors, and methods",
+ items: [
+ {
+ tag: "@function",
+ syntax: "@function",
+ example: "/**\n * @function calculateTotal\n * @description Calculates order total\n */",
+ description: "Explicitly marks something as a function",
+ },
+ {
+ tag: "@class",
+ syntax: "@class",
+ example: "/**\n * @class\n * @description Represents a user account\n */",
+ description: "Documents a class",
+ },
+ {
+ tag: "@constructor",
+ syntax: "@constructor",
+ example: "/**\n * @constructor\n * @param {string} name - User name\n */",
+ description: "Documents a constructor function",
+ },
+ {
+ tag: "@method",
+ syntax: "@method",
+ example: "/**\n * @method getName\n * @returns {string} The user name\n */",
+ description: "Documents a method",
+ },
+ {
+ tag: "@static",
+ syntax: "@static",
+ example: "/**\n * @static\n * @method createUser\n */",
+ description: "Indicates a static method or property",
+ },
+ {
+ tag: "@override",
+ syntax: "@override",
+ example: "/**\n * @override\n * @method toString\n */",
+ description: "Indicates method overrides parent method",
+ },
+ ],
+ },
+ modules: {
+ title: "Modules & Namespaces",
+ description: "Organize code with modules, namespaces, and membership",
+ items: [
+ {
+ tag: "@module",
+ syntax: "@module ModuleName",
+ example: "/**\n * @module UserUtils\n * @description Utilities for user management\n */",
+ description: "Documents a module",
+ },
+ {
+ tag: "@namespace",
+ syntax: "@namespace NamespaceName",
+ example: "/**\n * @namespace MyApp.Utils\n */",
+ description: "Documents a namespace",
+ },
+ {
+ tag: "@memberof",
+ syntax: "@memberof ParentName",
+ example: "/**\n * @memberof MyApp.Utils\n * @function formatName\n */",
+ description: "Indicates membership in a parent",
+ },
+ {
+ tag: "@exports",
+ syntax: "@exports ModuleName",
+ example: "/**\n * @exports UserService\n */",
+ description: "Documents what a module exports",
+ },
+ {
+ tag: "@requires",
+ syntax: "@requires ModuleName",
+ example: "/**\n * @requires lodash\n */",
+ description: "Documents module dependencies",
+ },
+ ],
+ },
+ advanced: {
+ title: "Advanced Tags",
+ description: "Advanced JSDoc features for complex documentation needs",
+ items: [
+ {
+ tag: "@callback",
+ syntax: "@callback CallbackName",
+ example: "/**\n * @callback RequestCallback\n * @param {Error} error\n * @param {Object} response\n */",
+ description: "Documents a callback function type",
+ },
+ {
+ tag: "@event",
+ syntax: "@event EventName",
+ example: "/**\n * @event MyClass#dataLoaded\n * @type {Object}\n */",
+ description: "Documents an event",
+ },
+ {
+ tag: "@fires",
+ syntax: "@fires EventName",
+ example: "/**\n * @fires MyClass#dataLoaded\n */",
+ description: "Indicates function fires an event",
+ },
+ {
+ tag: "@listens",
+ syntax: "@listens EventName",
+ example: "/**\n * @listens MyClass#dataLoaded\n */",
+ description: "Indicates function listens to an event",
+ },
+ {
+ tag: "@mixes",
+ syntax: "@mixes MixinName",
+ example: "/**\n * @mixes EventEmitter\n */",
+ description: "Documents that class mixes in another",
+ },
+ {
+ tag: "@abstract",
+ syntax: "@abstract",
+ example: "/**\n * @abstract\n * @method process\n */",
+ description: "Indicates abstract method or class",
+ },
+ ],
+ },
+ examples: {
+ title: "Complete Examples",
+ description: "Real-world JSDoc documentation examples",
+ items: [
+ {
+ tag: "Function Example",
+ syntax: "Complete function documentation",
+ example: `/**
+ * Calculates the area of a rectangle
+ * @function calculateArea
+ * @param {number} width - The width of the rectangle
+ * @param {number} height - The height of the rectangle
+ * @returns {number} The area of the rectangle
+ * @throws {TypeError} When width or height is not a number
+ * @example
+ * // Calculate area of 5x3 rectangle
+ * const area = calculateArea(5, 3);
+ * console.log(area); // 15
+ * @since 1.0.0
+ * @author Jane Smith
+ */
+function calculateArea(width, height) {
+ if (typeof width !== 'number' || typeof height !== 'number') {
+ throw new TypeError('Width and height must be numbers');
+ }
+ return width * height;
+}`,
+ description: "Complete function documentation with all common tags",
+ },
+ {
+ tag: "Class Example",
+ syntax: "Complete class documentation",
+ example: `/**
+ * Represents a user in the system
+ * @class User
+ * @param {string} name - The user's name
+ * @param {string} email - The user's email address
+ * @example
+ * const user = new User('John Doe', 'john@example.com');
+ * console.log(user.getName()); // 'John Doe'
+ */
+class User {
+ /**
+ * Create a user
+ * @constructor
+ * @param {string} name - The user's name
+ * @param {string} email - The user's email address
+ */
+ constructor(name, email) {
+ this.name = name;
+ this.email = email;
+ }
+
+ /**
+ * Get the user's name
+ * @method getName
+ * @returns {string} The user's name
+ */
+ getName() {
+ return this.name;
+ }
+}`,
+ description: "Complete class documentation with constructor and methods",
+ },
+ {
+ tag: "Module Example",
+ syntax: "Complete module documentation",
+ example: `/**
+ * User management module
+ * @module UserManagement
+ * @description Handles user creation and deletion
+ * @requires Database
+ * @requires EmailService
+ * @exports createUser
+ * @exports deleteUser
+ * @example
+ * // Create a user
+ * const user = createUser('John Doe', 'john@example.com');
+ * console.log(user);
+ *
+ * // Delete a user
+ * deleteUser(user.id);
+ */
+const Database = require('./Database');
+const EmailService = require('./EmailService');
+
+function createUser(name, email) {
+ // Implementation here
+}
+
+function deleteUser(userId) {
+ // Implementation here
+}
+
+module.exports = {
+ createUser,
+ deleteUser
+};`,
+ description: "Complete module documentation with dependencies and exports",
+ },
+ ],
+ },
+ "best-practices": {
+ title: "Best Practices",
+ description: "Guidelines for writing effective JSDoc documentation",
+ items: [
+ {
+ tag: "Consistency",
+ syntax: "Use consistent formatting and style",
+ example:
+ "// Always use the same format for similar tags\n// Good: @param {string} name - User name\n// Good: @param {number} age - User age",
+ description: "Maintain consistent formatting across your documentation",
+ },
+ {
+ tag: "Completeness",
+ syntax: "Document all public APIs",
+ example: "// Document all parameters, return values, and exceptions\n// Include examples for complex functions",
+ description: "Ensure all public functions, classes, and modules are documented",
+ },
+ {
+ tag: "Clarity",
+ syntax: "Write clear, concise descriptions",
+ example: "// Good: Calculates user age from birth date\n// Bad: Does age stuff",
+ description: "Use clear, descriptive language that explains purpose and behavior",
+ },
+ {
+ tag: "Type Safety",
+ syntax: "Always specify types for parameters and returns",
+ example:
+ "// Always include types\n@param {string|null} name - User name or null\n@returns {Promise} Promise resolving to user object",
+ description: "Include detailed type information to improve code reliability",
+ },
+ {
+ tag: "Examples",
+ syntax: "Include usage examples for complex functions",
+ example:
+ "/**\n * @example\n * // Basic usage\n * const result = myFunction('input');\n * \n * @example\n * // Advanced usage\n * const result = myFunction('input', { option: true });\n */",
+ description: "Provide practical examples showing how to use the code",
+ },
+ ],
+ },
+ objects: {
+ title: "Objects & Interfaces",
+ description: "Document object structures, interfaces, and inheritance",
+ items: [
+ {
+ tag: "@interface",
+ syntax: "@interface InterfaceName",
+ example: "/**\n * @interface Drawable\n * @description Interface for drawable objects\n */",
+ description: "Documents an interface that classes can implement",
+ },
+ {
+ tag: "@implements",
+ syntax: "@implements {InterfaceName}",
+ example: "/**\n * @class Circle\n * @implements {Drawable}\n */",
+ description: "Indicates that a class implements an interface",
+ },
+ {
+ tag: "@extends",
+ syntax: "@extends ParentClass",
+ example: "/**\n * @class ColoredCircle\n * @extends Circle\n */",
+ description: "Documents class inheritance",
+ },
+ {
+ tag: "@mixin",
+ syntax: "@mixin MixinName",
+ example: "/**\n * @mixin EventEmitter\n * @description Adds event handling capabilities\n */",
+ description: "Documents a mixin that can be mixed into classes",
+ },
+ ],
+ },
+ documentation: {
+ title: "Documentation Tags",
+ description: "Tags for linking, examples, and additional documentation",
+ items: [
+ {
+ tag: "@example",
+ syntax: "@example\n// Example code here",
+ example:
+ "/**\n * @example\n * // Basic usage\n * const result = myFunction('test');\n * console.log(result);\n */",
+ description: "Provides usage examples",
+ },
+ {
+ tag: "@see",
+ syntax: "@see {reference}",
+ example: "/**\n * @see {@link MyClass#method}\n * @see https://example.com/docs\n */",
+ description: "References related documentation or code",
+ },
+ {
+ tag: "@link",
+ syntax: "{@link reference}",
+ example: "/**\n * Uses {@link MyClass} for processing\n */",
+ description: "Creates inline links to other documentation",
+ },
+ {
+ tag: "@tutorial",
+ syntax: "@tutorial TutorialName",
+ example: "/**\n * @tutorial getting-started\n */",
+ description: "Links to a tutorial document",
+ },
+ {
+ tag: "@todo",
+ syntax: "@todo Description of what needs to be done",
+ example: "/**\n * @todo Add input validation\n * @todo Optimize performance\n */",
+ description: "Documents future improvements or fixes needed",
+ },
+ ],
+ },
+}
+
+export default function JSDocCheatsheet() {
+ const [activeSection, setActiveSection] = useState("kitchen-sink")
+ const [expandedSections, setExpandedSections] = useState(["kitchen-sink"])
+ const [isScrolling, setIsScrolling] = useState(false)
+
+ const toggleSection = (sectionId: string) => {
+ setExpandedSections((prev) =>
+ prev.includes(sectionId) ? prev.filter((id) => id !== sectionId) : [...prev, sectionId],
+ )
+ }
+
+ const scrollToTag = (tag: string) => {
+ const element = document.getElementById(tag.replace("@", "").replace(/[^a-zA-Z0-9]/g, "-"))
+ if (element) {
+ setIsScrolling(true)
+ element.scrollIntoView({ behavior: "smooth", block: "start" })
+
+ // Reset scrolling state after animation
+ setTimeout(() => setIsScrolling(false), 1000)
+
+ // Highlight the element briefly
+ element.classList.add("ring-2", "ring-primary", "ring-opacity-50")
+ setTimeout(() => {
+ element.classList.remove("ring-2", "ring-primary", "ring-opacity-50")
+ }, 2000)
+ }
+ }
+
+ useEffect(() => {
+ const handleScroll = () => {
+ if (isScrolling) return // Don't update during programmatic scrolling
+
+ const sections = Object.keys(jsdocData)
+ const scrollPosition = window.scrollY + 200
+
+ for (const sectionId of sections) {
+ const element = document.getElementById(`section-${sectionId}`)
+ if (element) {
+ const { offsetTop, offsetHeight } = element
+ if (scrollPosition >= offsetTop && scrollPosition < offsetTop + offsetHeight) {
+ setActiveSection(sectionId)
+ break
+ }
+ }
+ }
+ }
+
+ window.addEventListener("scroll", handleScroll)
+ return () => window.removeEventListener("scroll", handleScroll)
+ }, [isScrolling])
+
+ return (
+
+ {/* Header */}
+
+
+
+
JSDoc Cheatsheet
+
Complete Reference for JavaScript Documentation
+
+
+
+
+
+
+ {/* Sidebar Navigation */}
+
+
+ {/* Main Content */}
+
+
+ {/* Kitchen Sink Example */}
+
+
+
+
+ Kitchen Sink Example
+
+
+
+ A comprehensive example showcasing multiple JSDoc features in one code block
+
+
+
+
+
+
+
+ {/* Section Header */}
+
+
+ {jsdocData[activeSection as keyof typeof jsdocData]?.title || "Section"}
+
+
+ {jsdocData[activeSection as keyof typeof jsdocData]?.description || "Documentation section"}
+
+
+
+ {/* Content Cards */}
+
+ {jsdocData[activeSection as keyof typeof jsdocData]?.items.map((item, index) => (
+
+
+
+
+
+ {item.tag}
+
+
+
+ {item.description}
+
+
+ {/* Syntax */}
+
+
Syntax:
+
+ {item.syntax}
+
+
+
+
+
+ {/* Example with Syntax Highlighting */}
+
+
Example:
+
+
+
+
+ )) || []}
+
+
+
+
+
+
+ {/* Footer */}
+
+
+ )
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 097ad84..693f308 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"react-dom": "^18",
"react-hook-form": "^7.60.0",
"react-resizable-panels": "^2.1.7",
+ "react-syntax-highlighter": "^15.6.6",
"recharts": "2.15.4",
"sonner": "^1.7.4",
"tailwind-merge": "^2.5.5",
@@ -66,6 +67,7 @@
"@types/node": "^22",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "@types/react-syntax-highlighter": "^15.5.13",
"postcss": "^8.5",
"tailwindcss": "^4.1.9",
"tw-animate-css": "1.3.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2fc6f16..574a5e2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -143,6 +143,9 @@ importers:
react-resizable-panels:
specifier: ^2.1.7
version: 2.1.7(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ react-syntax-highlighter:
+ specifier: ^15.6.6
+ version: 15.6.6(react@18.0.0)
recharts:
specifier: 2.15.4
version: 2.15.4(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
@@ -174,6 +177,9 @@ importers:
'@types/react-dom':
specifier: ^18
version: 18.0.0
+ '@types/react-syntax-highlighter':
+ specifier: ^15.5.13
+ version: 15.5.13
postcss:
specifier: ^8.5
version: 8.5.0
@@ -1121,6 +1127,9 @@ packages:
'@types/d3-timer@3.0.2':
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
+ '@types/hast@2.3.10':
+ resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==}
+
'@types/node@22.0.0':
resolution: {integrity: sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==}
@@ -1130,12 +1139,18 @@ packages:
'@types/react-dom@18.0.0':
resolution: {integrity: sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg==}
+ '@types/react-syntax-highlighter@15.5.13':
+ resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==}
+
'@types/react@18.0.0':
resolution: {integrity: sha512-7+K7zEQYu7NzOwQGLR91KwWXXDzmTFODRVizJyIALf6RfLv2GDpqpknX64pvRVILXCpXi7O/pua8NGk44dLvJw==}
'@types/scheduler@0.26.0':
resolution: {integrity: sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==}
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
'@vercel/analytics@1.5.0':
resolution: {integrity: sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==}
peerDependencies:
@@ -1189,6 +1204,15 @@ packages:
caniuse-lite@1.0.30001743:
resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==}
+ character-entities-legacy@1.1.4:
+ resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
+
+ character-entities@1.2.4:
+ resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
+
+ character-reference-invalid@1.1.4:
+ resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
+
chownr@3.0.0:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'}
@@ -1209,6 +1233,9 @@ packages:
react: ^18 || ^19 || ^19.0.0-rc
react-dom: ^18 || ^19 || ^19.0.0-rc
+ comma-separated-tokens@1.0.8:
+ resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
+
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -1306,6 +1333,13 @@ packages:
resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==}
engines: {node: '>=6.0.0'}
+ fault@1.0.4:
+ resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
+
+ format@0.2.2:
+ resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
+ engines: {node: '>=0.4.x'}
+
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
@@ -1321,6 +1355,18 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ hast-util-parse-selector@2.2.5:
+ resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
+
+ hastscript@6.0.0:
+ resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==}
+
+ highlight.js@10.7.3:
+ resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
+
+ highlightjs-vue@1.0.0:
+ resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==}
+
input-otp@1.4.1:
resolution: {integrity: sha512-+yvpmKYKHi9jIGngxagY9oWiiblPB7+nEO75F2l2o4vs+6vpPZZmUl4tBNYuTCvQjhvEIbdNeJu70bhfYP2nbw==}
peerDependencies:
@@ -1331,6 +1377,18 @@ packages:
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
engines: {node: '>=12'}
+ is-alphabetical@1.0.4:
+ resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
+
+ is-alphanumerical@1.0.4:
+ resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
+
+ is-decimal@1.0.4:
+ resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
+
+ is-hexadecimal@1.0.4:
+ resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
+
jiti@2.5.1:
resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==}
hasBin: true
@@ -1409,6 +1467,9 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ lowlight@1.20.0:
+ resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
+
lucide-react@0.454.0:
resolution: {integrity: sha512-hw7zMDwykCLnEzgncEEjHeA6+45aeEzRYuKHuyRSOPkhko+J3ySGjGIzu+mmMfDFG1vazHepMaYFYHbTFAZAAQ==}
peerDependencies:
@@ -1470,6 +1531,9 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
+ parse-entities@2.0.0:
+ resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
+
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -1484,9 +1548,20 @@ packages:
resolution: {integrity: sha512-27VKOqrYfPncKA2NrFOVhP5MGAfHKLYn/Q0mz9cNQyRAKYi3VNHwYU2qKKqPCqgBmeeJ0uAFB56NumXZ5ZReXg==}
engines: {node: ^10 || ^12 || >=14}
+ prismjs@1.27.0:
+ resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
+ engines: {node: '>=6'}
+
+ prismjs@1.30.0:
+ resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
+ engines: {node: '>=6'}
+
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ property-information@5.6.0:
+ resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
+
react-day-picker@9.8.0:
resolution: {integrity: sha512-E0yhhg7R+pdgbl/2toTb0xBhsEAtmAx1l7qjIWYfcxOy8w4rTSVfbtBoSzVVhPwKP/5E9iL38LivzoE3AQDhCQ==}
engines: {node: '>=18'}
@@ -1552,6 +1627,11 @@ packages:
'@types/react':
optional: true
+ react-syntax-highlighter@15.6.6:
+ resolution: {integrity: sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==}
+ peerDependencies:
+ react: '>= 0.14.0'
+
react-transition-group@4.4.5:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies:
@@ -1572,6 +1652,9 @@ packages:
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
+ refractor@3.6.0:
+ resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
+
scheduler@0.21.0:
resolution: {integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==}
@@ -1585,6 +1668,9 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
+ space-separated-tokens@1.1.5:
+ resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
+
streamsearch@1.1.0:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
@@ -1678,6 +1764,10 @@ packages:
victory-vendor@36.9.2:
resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==}
+ xtend@4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+
yallist@5.0.0:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
@@ -2593,6 +2683,10 @@ snapshots:
'@types/d3-timer@3.0.2': {}
+ '@types/hast@2.3.10':
+ dependencies:
+ '@types/unist': 2.0.11
+
'@types/node@22.0.0':
dependencies:
undici-types: 6.11.1
@@ -2603,6 +2697,10 @@ snapshots:
dependencies:
'@types/react': 18.0.0
+ '@types/react-syntax-highlighter@15.5.13':
+ dependencies:
+ '@types/react': 18.0.0
+
'@types/react@18.0.0':
dependencies:
'@types/prop-types': 15.7.15
@@ -2611,6 +2709,8 @@ snapshots:
'@types/scheduler@0.26.0': {}
+ '@types/unist@2.0.11': {}
+
'@vercel/analytics@1.5.0(next@14.2.16(react-dom@18.0.0(react@18.0.0))(react@18.0.0))(react@18.0.0)':
optionalDependencies:
next: 14.2.16(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
@@ -2646,6 +2746,12 @@ snapshots:
caniuse-lite@1.0.30001743: {}
+ character-entities-legacy@1.1.4: {}
+
+ character-entities@1.2.4: {}
+
+ character-reference-invalid@1.1.4: {}
+
chownr@3.0.0: {}
class-variance-authority@0.7.1:
@@ -2668,6 +2774,8 @@ snapshots:
- '@types/react'
- '@types/react-dom'
+ comma-separated-tokens@1.0.8: {}
+
csstype@3.1.3: {}
d3-array@3.2.4:
@@ -2748,6 +2856,12 @@ snapshots:
fast-equals@5.2.2: {}
+ fault@1.0.4:
+ dependencies:
+ format: 0.2.2
+
+ format@0.2.2: {}
+
fraction.js@4.3.7: {}
geist@1.5.1(next@14.2.16(react-dom@18.0.0(react@18.0.0))(react@18.0.0)):
@@ -2758,6 +2872,20 @@ snapshots:
graceful-fs@4.2.11: {}
+ hast-util-parse-selector@2.2.5: {}
+
+ hastscript@6.0.0:
+ dependencies:
+ '@types/hast': 2.3.10
+ comma-separated-tokens: 1.0.8
+ hast-util-parse-selector: 2.2.5
+ property-information: 5.6.0
+ space-separated-tokens: 1.1.5
+
+ highlight.js@10.7.3: {}
+
+ highlightjs-vue@1.0.0: {}
+
input-otp@1.4.1(react-dom@18.0.0(react@18.0.0))(react@18.0.0):
dependencies:
react: 18.0.0
@@ -2765,6 +2893,17 @@ snapshots:
internmap@2.0.3: {}
+ is-alphabetical@1.0.4: {}
+
+ is-alphanumerical@1.0.4:
+ dependencies:
+ is-alphabetical: 1.0.4
+ is-decimal: 1.0.4
+
+ is-decimal@1.0.4: {}
+
+ is-hexadecimal@1.0.4: {}
+
jiti@2.5.1: {}
js-tokens@4.0.0: {}
@@ -2820,6 +2959,11 @@ snapshots:
dependencies:
js-tokens: 4.0.0
+ lowlight@1.20.0:
+ dependencies:
+ fault: 1.0.4
+ highlight.js: 10.7.3
+
lucide-react@0.454.0(react@18.0.0):
dependencies:
react: 18.0.0
@@ -2874,6 +3018,15 @@ snapshots:
object-assign@4.1.1: {}
+ parse-entities@2.0.0:
+ dependencies:
+ character-entities: 1.2.4
+ character-entities-legacy: 1.1.4
+ character-reference-invalid: 1.1.4
+ is-alphanumerical: 1.0.4
+ is-decimal: 1.0.4
+ is-hexadecimal: 1.0.4
+
picocolors@1.1.1: {}
postcss-value-parser@4.2.0: {}
@@ -2890,12 +3043,20 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
+ prismjs@1.27.0: {}
+
+ prismjs@1.30.0: {}
+
prop-types@15.8.1:
dependencies:
loose-envify: 1.4.0
object-assign: 4.1.1
react-is: 16.13.1
+ property-information@5.6.0:
+ dependencies:
+ xtend: 4.0.2
+
react-day-picker@9.8.0(react@18.0.0):
dependencies:
'@date-fns/tz': 1.2.0
@@ -2957,6 +3118,16 @@ snapshots:
optionalDependencies:
'@types/react': 18.0.0
+ react-syntax-highlighter@15.6.6(react@18.0.0):
+ dependencies:
+ '@babel/runtime': 7.28.4
+ highlight.js: 10.7.3
+ highlightjs-vue: 1.0.0
+ lowlight: 1.20.0
+ prismjs: 1.30.0
+ react: 18.0.0
+ refractor: 3.6.0
+
react-transition-group@4.4.5(react-dom@18.0.0(react@18.0.0))(react@18.0.0):
dependencies:
'@babel/runtime': 7.28.4
@@ -2987,6 +3158,12 @@ snapshots:
tiny-invariant: 1.3.3
victory-vendor: 36.9.2
+ refractor@3.6.0:
+ dependencies:
+ hastscript: 6.0.0
+ parse-entities: 2.0.0
+ prismjs: 1.27.0
+
scheduler@0.21.0:
dependencies:
loose-envify: 1.4.0
@@ -2998,6 +3175,8 @@ snapshots:
source-map-js@1.2.1: {}
+ space-separated-tokens@1.1.5: {}
+
streamsearch@1.1.0: {}
styled-jsx@5.1.1(react@18.0.0):
@@ -3085,6 +3264,8 @@ snapshots:
d3-time: 3.1.0
d3-timer: 3.0.1
+ xtend@4.0.2: {}
+
yallist@5.0.0: {}
zod@3.25.67: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..fd050a4
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,2 @@
+onlyBuiltDependencies:
+ - '@tailwindcss/oxide'