/** * Felix Framework - Educational Interface with Guided Tours * * Comprehensive educational system for Felix Framework with interactive * tutorials, step-by-step guided tours, contextual help, and progressive * learning paths for understanding helix-based multi-agent cognitive architecture. * * Features: * - Interactive step-by-step tutorials * - Contextual help and tooltips * - Progressive learning paths * - Visual demonstration overlays * - Knowledge checkpoints and quizzes * - Adaptive content based on user progress * - Mobile-optimized educational content * - Multi-language support preparation * * @version 1.0.0 * @author Felix Framework Team */ import { EducationalContent, TourStep, TourAction, TourValidation, ContentType, DifficultyLevel, ContentResource } from '../types/gradio-interface'; import { AgentType, AgentState, HelixGeometry } from '../types/felix-core'; // ============================================================================= // Educational Content Types // ============================================================================= /** Educational module configuration */ export interface EducationalModule { readonly id: string; readonly title: string; readonly description: string; readonly difficulty: DifficultyLevel; readonly estimatedMinutes: number; readonly prerequisites: readonly string[]; readonly learningObjectives: readonly string[]; readonly content: readonly EducationalContent[]; readonly tour?: GuidedTour; readonly quiz?: QuizConfiguration; readonly resources: readonly ContentResource[]; } /** Guided tour configuration */ export interface GuidedTour { readonly id: string; readonly title: string; readonly description: string; readonly steps: readonly TourStep[]; readonly canSkip: boolean; readonly autoProgress: boolean; readonly completionCriteria: CompletionCriteria; } /** Quiz configuration */ export interface QuizConfiguration { readonly id: string; readonly title: string; readonly questions: readonly QuizQuestion[]; readonly passingScore: number; readonly allowRetakes: boolean; readonly showCorrectAnswers: boolean; } /** Quiz question types */ export interface QuizQuestion { readonly id: string; readonly type: QuestionType; readonly question: string; readonly options?: readonly string[]; readonly correctAnswer: string | readonly string[]; readonly explanation?: string; readonly points: number; } /** Question types */ export enum QuestionType { MultipleChoice = 'multiple_choice', TrueFalse = 'true_false', ShortAnswer = 'short_answer', MultipleSelect = 'multiple_select', Ordering = 'ordering', Matching = 'matching' } /** Completion criteria */ export interface CompletionCriteria { readonly visitAllSteps: boolean; readonly completeActions: boolean; readonly passQuiz?: boolean; readonly timeSpentMinimum?: number; readonly customValidation?: (progress: TourProgress) => boolean; } /** Tour progress tracking */ export interface TourProgress { readonly tourId: string; readonly currentStepIndex: number; readonly completedSteps: Set; readonly startTime: number; readonly timeSpentSeconds: number; readonly actionsCompleted: number; readonly validationsPassed: number; readonly isCompleted: boolean; } /** User learning profile */ export interface UserLearningProfile { readonly userId: string; readonly completedModules: Set; readonly completedTours: Set; readonly currentDifficulty: DifficultyLevel; readonly preferredPace: LearningPace; readonly strengths: readonly string[]; readonly needsImprovement: readonly string[]; readonly totalTimeSpent: number; readonly achievementsBadges: readonly string[]; } /** Learning pace preferences */ export enum LearningPace { Slow = 'slow', Medium = 'medium', Fast = 'fast', SelfPaced = 'self_paced' } // ============================================================================= // Educational Content Definitions // ============================================================================= /** Core Felix Framework educational modules */ export const FELIX_EDUCATIONAL_MODULES: readonly EducationalModule[] = [ { id: 'felix_introduction', title: 'Introduction to Felix Framework', description: 'Learn the fundamentals of helix-based multi-agent cognitive architecture', difficulty: DifficultyLevel.Beginner, estimatedMinutes: 15, prerequisites: [], learningObjectives: [ 'Understand the concept of helix-based coordination', 'Learn about agent specialization and roles', 'Recognize the advantages over traditional architectures', 'Identify key components of the Felix system' ], content: [ { id: 'intro_overview', title: 'What is Felix Framework?', content: ` # Welcome to Felix Framework! 🌪️ Felix Framework revolutionizes multi-agent AI coordination through **helix-based cognitive architecture**. Unlike traditional graph-based systems, Felix uses geometric spiral paths for natural agent convergence. ## Key Innovation: The Helix Model The helix structure provides: - **Natural Convergence**: Agents spiral from broad exploration to focused synthesis - **Automatic Focusing**: Geometric tapering concentrates attention naturally - **Efficient Communication**: O(N) spoke-based messaging vs O(N²) mesh complexity - **Scalable Architecture**: Linear performance scaling up to 133+ agents ## Research Validation ✅ Felix has been rigorously tested with: - 107+ passing unit tests - Mathematical precision < 1e-12 error - Statistical significance testing (H1 supported, p=0.0441) - 75% memory efficiency improvement over mesh systems Ready to explore this innovative approach to AI coordination? `, type: ContentType.Introduction, difficulty: DifficultyLevel.Beginner, estimatedTime: 5, prerequisites: [], resources: [ { type: 'paper', title: 'Felix Framework Research Paper', url: 'https://github.com/CalebisGross/thefelix/blob/main/RESEARCH_LOG.md', description: 'Complete research documentation and validation' } ] } ], tour: { id: 'felix_intro_tour', title: 'Felix Framework Overview Tour', description: 'Interactive introduction to Felix Framework interface and concepts', canSkip: true, autoProgress: false, steps: [ { id: 'welcome', target: 'body', title: 'Welcome to Felix Framework!', content: 'Let\'s explore the revolutionary helix-based multi-agent cognitive architecture. This tour will guide you through the key concepts and interface.', position: 'center', action: { type: 'highlight', duration: 2000 } }, { id: 'helix_visualization', target: '#helix-plot', title: 'The Helix Visualization', content: 'This 3D helix represents the core of Felix Framework. Agents spawn at the top (broad exploration) and spiral down to the bottom (focused synthesis). The geometry naturally concentrates attention with a 33,000x focusing ratio.', position: 'right', action: { type: 'click', value: 'camera_preset_default' }, validation: { condition: (state) => true, message: 'Great! You can see the helix structure.', retry: false } }, { id: 'agent_types', target: '#agent-selector', title: 'Agent Specialization', content: 'Felix uses four specialized agent types:\n🔍 Research (early spawn, high creativity)\n🧠 Analysis (mid-stage reasoning)\n🎨 Synthesis (late spawn, high precision)\n🔎 Critic (quality validation)', position: 'left' }, { id: 'task_input', target: '#task-input', title: 'Task Processing', content: 'Enter tasks here for multi-agent processing. Agents coordinate through the helix structure, naturally converging from broad exploration to focused solutions.', position: 'bottom' } ], completionCriteria: { visitAllSteps: true, completeActions: true } }, quiz: { id: 'felix_intro_quiz', title: 'Felix Framework Basics Quiz', passingScore: 80, allowRetakes: true, showCorrectAnswers: true, questions: [ { id: 'q1', type: QuestionType.MultipleChoice, question: 'What is the main geometric structure used in Felix Framework?', options: ['Linear pipeline', 'Mesh network', 'Helix spiral', 'Tree hierarchy'], correctAnswer: 'Helix spiral', explanation: 'Felix uses a helix spiral structure for natural agent convergence from broad exploration to focused synthesis.', points: 25 }, { id: 'q2', type: QuestionType.TrueFalse, question: 'Felix Framework has O(N²) communication complexity like traditional mesh systems.', correctAnswer: 'false', explanation: 'Felix uses O(N) spoke-based communication, which is more efficient than O(N²) mesh systems.', points: 25 }, { id: 'q3', type: QuestionType.MultipleSelect, question: 'Which agent types are available in Felix Framework? (Select all that apply)', options: ['Research', 'Analysis', 'Synthesis', 'Critic', 'Coordinator', 'Monitor'], correctAnswer: ['Research', 'Analysis', 'Synthesis', 'Critic'], explanation: 'Felix has four specialized agent types: Research, Analysis, Synthesis, and Critic.', points: 25 }, { id: 'q4', type: QuestionType.MultipleChoice, question: 'What is the concentration ratio of the Felix helix?', options: ['1,000x', '10,000x', '33,000x', '100,000x'], correctAnswer: '33,000x', explanation: 'The Felix helix has a 33,000x concentration ratio (33.0 top radius / 0.001 bottom radius).', points: 25 } ] }, resources: [ { type: 'link', title: 'GitHub Repository', url: 'https://github.com/CalebisGross/thefelix', description: 'Complete source code and documentation' }, { type: 'paper', title: 'Mathematical Model Documentation', url: 'https://github.com/CalebisGross/thefelix/blob/main/docs/architecture/core/mathematical_model.md', description: 'Detailed mathematical foundations' } ] }, { id: 'helix_geometry', title: 'Understanding Helix Geometry', description: 'Deep dive into the mathematical foundations of the Felix helix', difficulty: DifficultyLevel.Intermediate, estimatedMinutes: 20, prerequisites: ['felix_introduction'], learningObjectives: [ 'Understand parametric helix equations', 'Learn about concentration ratios and focusing', 'Explore agent positioning mathematics', 'Understand precision and validation requirements' ], content: [ { id: 'helix_math', title: 'Mathematical Foundation', content: ` # Helix Mathematics 📐 The Felix helix is defined by precise parametric equations that create a natural focusing mechanism. ## Parametric Equations **Position Vector**: r(t) = (R(t)cos(θ(t)), R(t)sin(θ(t)), Ht) Where: - **t ∈ [0,1]**: Parameter where t=0 is top, t=1 is bottom - **R(t) = R_bottom × (R_top/R_bottom)^t**: Radius function with exponential tapering - **θ(t) = 2πnt**: Angular function with n=33 complete turns - **H = 100**: Total height ## Key Parameters - **Top Radius**: 33.0 (broad exploration phase) - **Bottom Radius**: 0.001 (focused synthesis phase) - **Turns**: 33 complete rotations - **Height**: 100.0 units - **Concentration Ratio**: 33,000x focusing power ## Mathematical Precision Felix maintains mathematical precision of **<1e-12 error** against the OpenSCAD prototype, ensuring research-grade accuracy for cognitive architecture modeling. ## Agent Positioning Agents spawn at different t values along the helix: - Research agents: t ≈ 0.1 (near top, high creativity) - Analysis agents: t ≈ 0.5 (middle, balanced reasoning) - Synthesis agents: t ≈ 0.9 (near bottom, high precision) This positioning naturally implements temperature gradients for LLM creativity control. `, type: ContentType.Tutorial, difficulty: DifficultyLevel.Intermediate, estimatedTime: 10, prerequisites: ['felix_introduction'], resources: [] } ], tour: { id: 'helix_geometry_tour', title: 'Exploring Helix Mathematics', description: 'Interactive exploration of helix geometry and mathematical properties', canSkip: true, autoProgress: false, steps: [ { id: 'helix_parameters', target: '#helix-controls', title: 'Helix Parameter Controls', content: 'These controls let you modify the helix geometry. Try changing the top radius to see how it affects the concentration ratio and agent positioning.', position: 'right', action: { type: 'input', value: '25.0' } }, { id: 'concentration_demo', target: '#concentration-indicator', title: 'Concentration Visualization', content: 'The red dashed circles show the dramatic size difference between top and bottom. This 33,000x concentration creates natural attention focusing.', position: 'top' }, { id: 'agent_positioning', target: '#agent-positions', title: 'Agent Positioning Math', content: 'Watch how agents are positioned along the helix using the t parameter. Each agent type has optimal t values for their cognitive role.', position: 'bottom' } ], completionCriteria: { visitAllSteps: true, completeActions: true } }, resources: [ { type: 'file', title: 'OpenSCAD Prototype', url: 'https://github.com/CalebisGross/thefelix/blob/main/thefelix.md', description: 'Original 3D model demonstrating core concepts' } ] }, { id: 'agent_coordination', title: 'Multi-Agent Coordination', description: 'Learn how agents coordinate through the helix structure', difficulty: DifficultyLevel.Intermediate, estimatedMinutes: 25, prerequisites: ['felix_introduction', 'helix_geometry'], learningObjectives: [ 'Understand spoke-based communication', 'Learn agent lifecycle management', 'Explore task distribution patterns', 'Compare with traditional architectures' ], content: [ { id: 'coordination_overview', title: 'Agent Coordination Patterns', content: ` # Multi-Agent Coordination in Felix 🤝 Felix implements a novel coordination pattern that leverages geometric properties for efficient agent communication and task distribution. ## Spoke-Based Communication Unlike traditional mesh networks with O(N²) complexity, Felix uses **spoke-based communication**: - **Central Post**: Hub for all coordination - **Agent Spokes**: Direct O(N) connections to center - **No Agent-to-Agent**: Eliminates complex mesh routing - **Natural Load Balancing**: Geometric distribution handles traffic ## Agent Lifecycle 1. **Spawning**: Agents spawn at helix top at different times 2. **Traversal**: Natural progression down the helix spiral 3. **Specialization**: Temperature/creativity decreases with depth 4. **Coordination**: Spoke-based messaging throughout lifecycle 5. **Completion**: Natural convergence at bottom focus point ## Task Distribution Efficiency Research validation shows **statistically significant improvement** (p=0.0441) in task distribution efficiency compared to linear pipelines: - **H1 SUPPORTED**: Better task distribution through geometric properties - **Memory Efficiency**: 75% reduction vs mesh systems (1,200 vs 4,800 units) - **Scalability**: Linear performance up to 133+ agents ## Comparison with Traditional Architectures | Feature | Felix Helix | Linear Pipeline | Mesh Network | |---------|-------------|-----------------|--------------| | Communication | O(N) spokes | O(N×M) stages | O(N²) mesh | | Memory Usage | 1,200 units | 2,400 units | 4,800 units | | Scalability | Linear | Limited stages | Quadratic | | Natural Focus | Geometric | Manual | None | | Setup Complexity | Low | Medium | High | `, type: ContentType.Tutorial, difficulty: DifficultyLevel.Intermediate, estimatedTime: 15, prerequisites: ['felix_introduction'], resources: [] } ], tour: { id: 'coordination_tour', title: 'Agent Coordination Demo', description: 'See multi-agent coordination in action', canSkip: false, autoProgress: true, steps: [ { id: 'start_task', target: '#process-button', title: 'Start Multi-Agent Processing', content: 'Click to start a task and watch how agents coordinate through the helix structure.', position: 'top', action: { type: 'click' }, validation: { condition: (state) => (state as any).taskStarted === true, message: 'Task started! Watch the agent coordination.', retry: true } }, { id: 'observe_spawning', target: '#helix-plot', title: 'Agent Spawning Pattern', content: 'Notice how agents appear at different helix positions. Research agents spawn early (top), synthesis agents spawn late (bottom).', position: 'right' }, { id: 'spoke_communication', target: '#communication-indicator', title: 'Spoke Communication', content: 'The white dotted lines show spoke-based communication between agents and the central post. This O(N) pattern is much more efficient than mesh networks.', position: 'left' } ], completionCriteria: { visitAllSteps: true, completeActions: true, customValidation: (progress) => progress.actionsCompleted >= 1 } }, resources: [ { type: 'paper', title: 'Statistical Validation Results', url: 'https://github.com/CalebisGross/thefelix/blob/main/docs/architecture/core/hypothesis_mathematics.md', description: 'Complete statistical analysis and hypothesis testing' } ] }, { id: 'performance_optimization', title: 'Performance Optimization', description: 'Advanced techniques for optimizing Felix Framework performance', difficulty: DifficultyLevel.Advanced, estimatedMinutes: 30, prerequisites: ['felix_introduction', 'helix_geometry', 'agent_coordination'], learningObjectives: [ 'Understand performance bottlenecks', 'Learn optimization strategies', 'Configure for different environments', 'Monitor and analyze performance metrics' ], content: [ { id: 'performance_fundamentals', title: 'Performance Optimization Strategies', content: ` # Performance Optimization 🚀 Felix Framework provides multiple optimization strategies for different deployment scenarios and performance requirements. ## Key Performance Factors ### 1. Helix Resolution - **High Resolution (1000+ points)**: Better visual quality, higher GPU/CPU load - **Medium Resolution (500 points)**: Balanced quality/performance (default) - **Low Resolution (100-200 points)**: Maximum performance, suitable for mobile ### 2. Agent Management - **Max Agents**: Higher counts increase memory usage exponentially - **Spawn Timing**: Staggered spawning reduces instantaneous load - **Lifecycle Management**: Proper cleanup prevents memory leaks ### 3. Communication Optimization - **Spoke Efficiency**: O(N) complexity scales linearly - **Message Batching**: Group updates for better throughput - **Compression**: Reduce bandwidth for mobile/slow connections ### 4. Rendering Optimization - **WebGL Acceleration**: Use GPU for 3D rendering when available - **Level of Detail (LOD)**: Reduce complexity based on camera distance - **Frustum Culling**: Only render visible portions - **Animation Throttling**: Reduce frame rate on low-power devices ## Environment-Specific Optimizations ### Mobile Devices ```typescript { helixResolution: 150, updateInterval: 2000, renderingMode: 'mobile', compressionLevel: 6, enableAnimations: false } ``` ### High-Performance Desktop ```typescript { helixResolution: 1000, updateInterval: 250, renderingMode: 'quality', maxAgents: 50, enableGPU: true } ``` ### Cloud/Server Deployment ```typescript { memoryLimit: 2000, compressionLevel: 3, batchUpdates: true, cacheSize: 200 } ``` ## Performance Monitoring Felix provides comprehensive performance metrics: - **Response Time**: Agent coordination latency - **Memory Usage**: Heap allocation and GC pressure - **GPU Utilization**: Rendering performance - **Network Throughput**: Communication efficiency - **Error Rates**: System stability indicators ## Optimization Best Practices 1. **Start with Balanced Settings**: Use default configuration first 2. **Profile Before Optimizing**: Identify actual bottlenecks 3. **Test on Target Hardware**: Mobile performance varies significantly 4. **Monitor Continuously**: Performance can degrade over time 5. **Use Performance Presets**: Apply tested configurations for common scenarios `, type: ContentType.Tutorial, difficulty: DifficultyLevel.Advanced, estimatedTime: 20, prerequisites: ['agent_coordination'], resources: [] } ], resources: [ { type: 'link', title: 'Performance Benchmarking Guide', url: 'https://github.com/CalebisGross/thefelix/blob/main/benchmarks/', description: 'Detailed benchmarking tools and results' } ] } ]; // ============================================================================= // Educational Interface Manager // ============================================================================= export class EducationalInterfaceManager { private currentModule: EducationalModule | null = null; private currentTour: GuidedTour | null = null; private tourProgress: TourProgress | null = null; private userProfile: UserLearningProfile; private helpOverlay: HTMLElement | null = null; private tourOverlay: HTMLElement | null = null; constructor(userId: string = 'default_user') { this.userProfile = this.initializeUserProfile(userId); this.setupEventListeners(); } // ============================================================================= // Module Management // ============================================================================= /** * Get available educational modules */ public getAvailableModules(): readonly EducationalModule[] { return FELIX_EDUCATIONAL_MODULES.filter(module => this.hasPrerequisites(module.prerequisites) ); } /** * Start an educational module */ public startModule(moduleId: string): boolean { const module = FELIX_EDUCATIONAL_MODULES.find(m => m.id === moduleId); if (!module) return false; if (!this.hasPrerequisites(module.prerequisites)) { console.warn(`Missing prerequisites for module ${moduleId}`); return false; } this.currentModule = module; return true; } /** * Complete current module */ public completeModule(): void { if (this.currentModule) { this.userProfile.completedModules.add(this.currentModule.id); this.updateUserProgress(); this.currentModule = null; } } /** * Check if user has required prerequisites */ private hasPrerequisites(prerequisites: readonly string[]): boolean { return prerequisites.every(prereq => this.userProfile.completedModules.has(prereq) ); } // ============================================================================= // Guided Tour Management // ============================================================================= /** * Start a guided tour */ public startTour(tourId: string): boolean { const module = FELIX_EDUCATIONAL_MODULES.find(m => m.tour?.id === tourId); if (!module?.tour) return false; this.currentTour = module.tour; this.tourProgress = { tourId, currentStepIndex: 0, completedSteps: new Set(), startTime: Date.now(), timeSpentSeconds: 0, actionsCompleted: 0, validationsPassed: 0, isCompleted: false }; this.showTourStep(0); return true; } /** * Navigate to next tour step */ public nextTourStep(): boolean { if (!this.currentTour || !this.tourProgress) return false; const currentStep = this.currentTour.steps[this.tourProgress.currentStepIndex]; // Validate current step if required if (currentStep.validation && !this.validateTourStep(currentStep)) { return false; } // Mark current step as completed this.tourProgress.completedSteps.add(this.tourProgress.currentStepIndex); // Move to next step if (this.tourProgress.currentStepIndex < this.currentTour.steps.length - 1) { this.tourProgress.currentStepIndex++; this.showTourStep(this.tourProgress.currentStepIndex); return true; } else { this.completeTour(); return false; } } /** * Navigate to previous tour step */ public previousTourStep(): boolean { if (!this.tourProgress || this.tourProgress.currentStepIndex === 0) return false; this.tourProgress.currentStepIndex--; this.showTourStep(this.tourProgress.currentStepIndex); return true; } /** * Skip current tour */ public skipTour(): void { if (!this.currentTour || !this.currentTour.canSkip) return; this.hideTourOverlay(); this.currentTour = null; this.tourProgress = null; } /** * Complete current tour */ private completeTour(): void { if (!this.currentTour || !this.tourProgress) return; // Check completion criteria const criteria = this.currentTour.completionCriteria; const meetsVisitCriteria = !criteria.visitAllSteps || this.tourProgress.completedSteps.size === this.currentTour.steps.length; const meetsActionCriteria = !criteria.completeActions || this.tourProgress.actionsCompleted > 0; const meetsCustomCriteria = !criteria.customValidation || criteria.customValidation(this.tourProgress); if (meetsVisitCriteria && meetsActionCriteria && meetsCustomCriteria) { this.tourProgress.isCompleted = true; this.userProfile.completedTours.add(this.currentTour.id); this.updateUserProgress(); this.showTourCompletion(); } this.hideTourOverlay(); this.currentTour = null; this.tourProgress = null; } /** * Show current tour step */ private showTourStep(stepIndex: number): void { if (!this.currentTour) return; const step = this.currentTour.steps[stepIndex]; const targetElement = this.findTargetElement(step.target); if (!targetElement && step.target !== 'body') { console.warn(`Tour step target not found: ${step.target}`); return; } // Create or update tour overlay this.updateTourOverlay(step, stepIndex); // Perform step action if specified if (step.action) { this.performTourAction(step.action, targetElement); } // Highlight target element if (targetElement && step.target !== 'body') { this.highlightElement(targetElement); } } /** * Validate tour step completion */ private validateTourStep(step: TourStep): boolean { if (!step.validation || !this.tourProgress) return true; const isValid = step.validation.condition(this.getTourState()); if (!isValid && step.validation.retry) { // Show validation message and allow retry this.showValidationMessage(step.validation.message); return false; } if (isValid) { this.tourProgress.validationsPassed++; } return isValid; } /** * Perform tour action */ private performTourAction(action: TourAction, targetElement: Element | null): void { if (!this.tourProgress) return; switch (action.type) { case 'click': if (targetElement) { (targetElement as HTMLElement).click(); this.tourProgress.actionsCompleted++; } break; case 'input': if (targetElement && action.value) { (targetElement as HTMLInputElement).value = action.value; targetElement.dispatchEvent(new Event('input', { bubbles: true })); this.tourProgress.actionsCompleted++; } break; case 'highlight': if (targetElement) { this.highlightElement(targetElement, action.duration); } break; case 'wait': if (action.duration) { setTimeout(() => { if (this.currentTour?.autoProgress) { this.nextTourStep(); } }, action.duration); } break; } } // ============================================================================= // Contextual Help System // ============================================================================= /** * Show contextual help for element */ public showContextualHelp(elementId: string, content: string): void { const element = document.getElementById(elementId); if (!element) return; this.createHelpTooltip(element, content); } /** * Create help tooltip */ private createHelpTooltip(element: Element, content: string): void { // Remove existing tooltips this.removeExistingTooltips(); const tooltip = document.createElement('div'); tooltip.className = 'felix-help-tooltip'; tooltip.innerHTML = `
${content}
`; // Position tooltip const rect = element.getBoundingClientRect(); tooltip.style.position = 'absolute'; tooltip.style.top = `${rect.bottom + 10}px`; tooltip.style.left = `${rect.left}px`; tooltip.style.zIndex = '10000'; // Add to page document.body.appendChild(tooltip); // Add close handler const closeButton = tooltip.querySelector('.tooltip-close'); closeButton?.addEventListener('click', () => { tooltip.remove(); }); // Auto-remove after delay setTimeout(() => { if (tooltip.parentNode) { tooltip.remove(); } }, 10000); } /** * Remove existing tooltips */ private removeExistingTooltips(): void { const tooltips = document.querySelectorAll('.felix-help-tooltip'); tooltips.forEach(tooltip => tooltip.remove()); } // ============================================================================= // Quiz System // ============================================================================= /** * Start quiz for current module */ public startQuiz(): QuizSession | null { if (!this.currentModule?.quiz) return null; return new QuizSession(this.currentModule.quiz, this.userProfile); } // ============================================================================= // User Interface Management // ============================================================================= /** * Update tour overlay */ private updateTourOverlay(step: TourStep, stepIndex: number): void { if (!this.currentTour || !this.tourProgress) return; // Remove existing overlay this.hideTourOverlay(); // Create new overlay this.tourOverlay = document.createElement('div'); this.tourOverlay.className = 'felix-tour-overlay'; this.tourOverlay.innerHTML = `

${step.title}

${stepIndex + 1} of ${this.currentTour.steps.length}
${step.content}
`; // Position popup relative to target if (step.target !== 'body') { const targetElement = this.findTargetElement(step.target); if (targetElement) { this.positionTourPopup(targetElement, step.position); } } // Add event listeners this.setupTourEventListeners(); // Add to page document.body.appendChild(this.tourOverlay); } /** * Hide tour overlay */ private hideTourOverlay(): void { if (this.tourOverlay) { this.tourOverlay.remove(); this.tourOverlay = null; } // Remove highlights this.removeHighlights(); } /** * Position tour popup relative to target */ private positionTourPopup(targetElement: Element, position: string): void { if (!this.tourOverlay) return; const popup = this.tourOverlay.querySelector('.tour-popup') as HTMLElement; const rect = targetElement.getBoundingClientRect(); switch (position) { case 'top': popup.style.bottom = `${window.innerHeight - rect.top + 10}px`; popup.style.left = `${rect.left + rect.width / 2}px`; popup.style.transform = 'translateX(-50%)'; break; case 'bottom': popup.style.top = `${rect.bottom + 10}px`; popup.style.left = `${rect.left + rect.width / 2}px`; popup.style.transform = 'translateX(-50%)'; break; case 'left': popup.style.top = `${rect.top + rect.height / 2}px`; popup.style.right = `${window.innerWidth - rect.left + 10}px`; popup.style.transform = 'translateY(-50%)'; break; case 'right': popup.style.top = `${rect.top + rect.height / 2}px`; popup.style.left = `${rect.right + 10}px`; popup.style.transform = 'translateY(-50%)'; break; case 'center': popup.style.top = '50%'; popup.style.left = '50%'; popup.style.transform = 'translate(-50%, -50%)'; break; } } /** * Setup tour event listeners */ private setupTourEventListeners(): void { if (!this.tourOverlay) return; const prevBtn = this.tourOverlay.querySelector('.tour-prev'); const nextBtn = this.tourOverlay.querySelector('.tour-next'); const skipBtn = this.tourOverlay.querySelector('.tour-skip'); prevBtn?.addEventListener('click', () => this.previousTourStep()); nextBtn?.addEventListener('click', () => this.nextTourStep()); skipBtn?.addEventListener('click', () => this.skipTour()); // Keyboard navigation document.addEventListener('keydown', this.handleTourKeydown.bind(this)); } /** * Handle tour keyboard navigation */ private handleTourKeydown(event: KeyboardEvent): void { if (!this.currentTour) return; switch (event.key) { case 'ArrowRight': case 'Enter': event.preventDefault(); this.nextTourStep(); break; case 'ArrowLeft': event.preventDefault(); this.previousTourStep(); break; case 'Escape': event.preventDefault(); if (this.currentTour.canSkip) { this.skipTour(); } break; } } /** * Highlight target element */ private highlightElement(element: Element, duration?: number): void { element.classList.add('felix-tour-highlight'); if (duration) { setTimeout(() => { element.classList.remove('felix-tour-highlight'); }, duration); } } /** * Remove all highlights */ private removeHighlights(): void { const highlights = document.querySelectorAll('.felix-tour-highlight'); highlights.forEach(el => el.classList.remove('felix-tour-highlight')); } /** * Show tour completion message */ private showTourCompletion(): void { if (!this.currentTour) return; const completion = document.createElement('div'); completion.className = 'felix-tour-completion'; completion.innerHTML = `

🎉 Tour Completed!

You've successfully completed the ${this.currentTour.title} tour.

`; document.body.appendChild(completion); const closeBtn = completion.querySelector('.completion-close'); closeBtn?.addEventListener('click', () => { completion.remove(); }); setTimeout(() => { if (completion.parentNode) { completion.remove(); } }, 5000); } /** * Show validation message */ private showValidationMessage(message: string): void { const validation = document.createElement('div'); validation.className = 'felix-tour-validation'; validation.innerHTML = `

${message}

`; document.body.appendChild(validation); setTimeout(() => { validation.remove(); }, 3000); } // ============================================================================= // Utility Methods // ============================================================================= /** * Find target element for tour step */ private findTargetElement(selector: string): Element | null { if (selector === 'body') return document.body; // Try ID first, then querySelector return document.getElementById(selector.replace('#', '')) || document.querySelector(selector); } /** * Get current tour state for validation */ private getTourState(): Record { return { tourProgress: this.tourProgress, userProfile: this.userProfile, currentModule: this.currentModule, // Add more state as needed for validation }; } /** * Initialize user learning profile */ private initializeUserProfile(userId: string): UserLearningProfile { // In real implementation, this would load from storage return { userId, completedModules: new Set(), completedTours: new Set(), currentDifficulty: DifficultyLevel.Beginner, preferredPace: LearningPace.Medium, strengths: [], needsImprovement: [], totalTimeSpent: 0, achievementsBadges: [] }; } /** * Update user progress */ private updateUserProgress(): void { // In real implementation, this would save to storage/database console.log('User progress updated:', this.userProfile); } /** * Setup global event listeners */ private setupEventListeners(): void { // Help button clicks document.addEventListener('click', (event) => { const target = event.target as HTMLElement; if (target.classList.contains('felix-help-trigger')) { const helpContent = target.dataset.helpContent; if (helpContent) { this.showContextualHelp(target.id, helpContent); } } }); } // ============================================================================= // Public API // ============================================================================= /** * Get user learning progress */ public getUserProgress(): UserLearningProfile { return { ...this.userProfile }; } /** * Get recommended next module */ public getRecommendedModule(): EducationalModule | null { const available = this.getAvailableModules(); const incomplete = available.filter(module => !this.userProfile.completedModules.has(module.id) ); if (incomplete.length === 0) return null; // Sort by difficulty and prerequisites incomplete.sort((a, b) => { const difficultyOrder = { [DifficultyLevel.Beginner]: 0, [DifficultyLevel.Intermediate]: 1, [DifficultyLevel.Advanced]: 2, [DifficultyLevel.Expert]: 3 }; return difficultyOrder[a.difficulty] - difficultyOrder[b.difficulty] || a.prerequisites.length - b.prerequisites.length; }); return incomplete[0]; } /** * Dispose of resources */ public dispose(): void { this.hideTourOverlay(); this.removeExistingTooltips(); document.removeEventListener('keydown', this.handleTourKeydown); } } // ============================================================================= // Quiz Session Class // ============================================================================= export class QuizSession { private currentQuestionIndex: number = 0; private answers: Map = new Map(); private score: number = 0; private startTime: number = Date.now(); constructor( private readonly quiz: QuizConfiguration, private readonly userProfile: UserLearningProfile ) {} public getCurrentQuestion(): QuizQuestion | null { if (this.currentQuestionIndex >= this.quiz.questions.length) return null; return this.quiz.questions[this.currentQuestionIndex]; } public submitAnswer(answer: string | string[]): void { const currentQuestion = this.getCurrentQuestion(); if (!currentQuestion) return; this.answers.set(currentQuestion.id, answer); } public nextQuestion(): boolean { if (this.currentQuestionIndex < this.quiz.questions.length - 1) { this.currentQuestionIndex++; return true; } return false; } public previousQuestion(): boolean { if (this.currentQuestionIndex > 0) { this.currentQuestionIndex--; return true; } return false; } public finishQuiz(): QuizResult { this.calculateScore(); const result: QuizResult = { quizId: this.quiz.id, score: this.score, totalPoints: this.quiz.questions.reduce((sum, q) => sum + q.points, 0), passed: this.score >= this.quiz.passingScore, timeSpent: Date.now() - this.startTime, answers: new Map(this.answers), feedback: this.generateFeedback() }; return result; } private calculateScore(): void { this.score = 0; this.quiz.questions.forEach(question => { const userAnswer = this.answers.get(question.id); if (!userAnswer) return; const isCorrect = Array.isArray(question.correctAnswer) ? this.arraysEqual(userAnswer as string[], question.correctAnswer) : userAnswer === question.correctAnswer; if (isCorrect) { this.score += question.points; } }); } private arraysEqual(a: string[], b: string[]): boolean { if (a.length !== b.length) return false; const sortedA = [...a].sort(); const sortedB = [...b].sort(); return sortedA.every((val, index) => val === sortedB[index]); } private generateFeedback(): string[] { const feedback: string[] = []; if (this.score >= this.quiz.passingScore) { feedback.push('Congratulations! You passed the quiz.'); } else { feedback.push('You did not meet the passing score. Consider reviewing the material.'); } // Add specific feedback based on incorrect answers this.quiz.questions.forEach(question => { const userAnswer = this.answers.get(question.id); const isCorrect = Array.isArray(question.correctAnswer) ? this.arraysEqual(userAnswer as string[], question.correctAnswer) : userAnswer === question.correctAnswer; if (!isCorrect && question.explanation) { feedback.push(`Question "${question.question}": ${question.explanation}`); } }); return feedback; } } // ============================================================================= // Supporting Types // ============================================================================= export interface QuizResult { readonly quizId: string; readonly score: number; readonly totalPoints: number; readonly passed: boolean; readonly timeSpent: number; readonly answers: Map; readonly feedback: readonly string[]; } // Export for use in Gradio interface export default EducationalInterfaceManager;