enhanced-composition-generator.ts•16 kB
/**
* Enhanced Composition Generator for Browser Automation
* Generates rich educational compositions based on EuConquisto Composer patterns
* @version 2.0.0
* @created 2025-07-02
*/
export interface CompositionElement {
id: string;
type: string;
content_title: string | null;
padding_top?: number;
padding_bottom?: number;
[key: string]: any;
}
export interface CompositionData {
composition: {
id: string;
title: string;
description: string;
author: string;
created: string;
version: string;
metadata?: {
disciplina: string;
serie: string;
duracao_estimada: string;
tags: string[];
[key: string]: any;
};
elements: CompositionElement[];
};
}
export class EnhancedCompositionGenerator {
/**
* Generate a complete educational composition from a prompt
*/
generateComposition(
prompt: string,
subject: string = "Ciências",
gradeLevel: string = "7º ano",
customTitle?: string
): CompositionData {
const timestamp = Date.now();
const title = customTitle || this.extractTitle(prompt, subject);
const elements = this.generateElements(prompt, subject, gradeLevel);
return {
composition: {
id: `composition-${timestamp}`,
title: title,
description: `Composição educacional interativa sobre ${subject} para ${gradeLevel}`,
author: "Sistema Inteligente EuConquisto",
created: new Date().toISOString().split('T')[0],
version: "2.0.0",
metadata: {
disciplina: subject,
serie: gradeLevel,
duracao_estimada: this.estimateDuration(elements),
tags: this.generateTags(prompt, subject)
},
elements: elements
}
};
}
/**
* Extract or generate an appropriate title from the prompt
*/
private extractTitle(prompt: string, subject: string): string {
const promptLower = prompt.toLowerCase();
// Science topics
if (promptLower.includes('fotossíntese')) {
return 'Fotossíntese: Como as Plantas Produzem Alimento';
}
if (promptLower.includes('célula')) {
return 'A Célula: Unidade Básica da Vida';
}
if (promptLower.includes('sistema solar')) {
return 'Sistema Solar: Nossa Vizinhança Cósmica';
}
// Math topics
if (promptLower.includes('fração') || promptLower.includes('frações')) {
return 'Frações: Dividindo e Compartilhando';
}
if (promptLower.includes('equação') || promptLower.includes('equações')) {
return 'Equações: Resolvendo Problemas Matemáticos';
}
if (promptLower.includes('geometria')) {
return 'Geometria: Formas e Espaços';
}
// History topics
if (promptLower.includes('independência')) {
return 'Independência do Brasil: Nossa História';
}
if (promptLower.includes('descobrimento')) {
return 'O Descobrimento do Brasil';
}
// Default: extract main topic
const mainTopic = this.extractMainTopic(prompt);
return `${mainTopic}: Aprendendo de Forma Interativa`;
}
/**
* Generate appropriate elements based on the prompt and subject
*/
private generateElements(prompt: string, subject: string, gradeLevel: string): CompositionElement[] {
const elements: CompositionElement[] = [];
const timestamp = Date.now();
let elementCounter = 1;
// 1. Header element (always present)
elements.push(this.createHeaderElement(elementCounter++, subject, gradeLevel));
// 2. Introduction text
elements.push(this.createIntroductionElement(elementCounter++, prompt, subject));
// 3. Main content elements based on analysis
const contentElements = this.analyzeAndGenerateContent(prompt, subject, elementCounter);
elements.push(...contentElements);
elementCounter += contentElements.length;
// 4. Interactive elements based on learning goals
const interactiveElements = this.generateInteractiveElements(prompt, subject, elementCounter);
elements.push(...interactiveElements);
return elements;
}
/**
* Create header element
*/
private createHeaderElement(id: number, subject: string, gradeLevel: string): CompositionElement {
const subjectColors: Record<string, string> = {
'ciências': '#4CAF50',
'matemática': '#2196F3',
'português': '#FF9800',
'história': '#9C27B0',
'geografia': '#00BCD4',
'geral': '#607D8B'
};
const primaryColor = subjectColors[subject.toLowerCase()] || subjectColors['geral'];
return {
id: `head-${id}`,
type: "head-1",
content_title: null,
primary_color: "#FFFFFF",
secondary_color: primaryColor,
category: `<p>${subject.toUpperCase()} - ${gradeLevel}</p>`,
background_image: "https://images.unsplash.com/photo-1557804506-669a67965ba0?w=1920&h=400&fit=crop",
avatar: "https://ui-avatars.com/api/?name=Professor&background=" + primaryColor.substring(1) + "&color=fff&size=120",
avatar_border_color: primaryColor,
author_name: "<p>Professor(a) Virtual</p>",
author_office: `<p>Especialista em ${subject}</p>`,
show_category: true,
show_author_name: true,
show_divider: true
};
}
/**
* Create introduction text element
*/
private createIntroductionElement(id: number, prompt: string, subject: string): CompositionElement {
const topic = this.extractMainTopic(prompt);
const introText = `
<h2>Bem-vindo à nossa aula!</h2>
<p>Hoje vamos explorar <strong>${topic}</strong> de forma interativa e divertida.
Esta composição foi criada especialmente para você aprender de maneira envolvente e eficaz.</p>
<p>Ao longo desta aula, você vai:</p>
<ul>
<li>Compreender os conceitos fundamentais</li>
<li>Explorar exemplos práticos</li>
<li>Testar seus conhecimentos com atividades interativas</li>
</ul>`;
return {
id: `text-${id}`,
type: "text-2",
content_title: "Introdução",
padding_top: 35,
padding_bottom: 35,
background_color: "#FFFFFF",
text: introText,
text_align: "justify",
font_size: 16,
line_height: 1.6
};
}
/**
* Analyze prompt and generate appropriate content elements
*/
private analyzeAndGenerateContent(prompt: string, subject: string, startId: number): CompositionElement[] {
const elements: CompositionElement[] = [];
const promptLower = prompt.toLowerCase();
let currentId = startId;
// Main content text
elements.push({
id: `text-${currentId++}`,
type: "text-1",
content_title: null,
padding_top: 20,
padding_bottom: 20,
background_color: "#FFFFFF",
text: this.generateMainContent(prompt, subject)
});
// Add visual elements if appropriate
if (this.shouldIncludeVisuals(prompt)) {
elements.push({
id: `image-${currentId++}`,
type: "image-1",
content_title: "Ilustração Explicativa",
padding_top: 20,
padding_bottom: 20,
image: this.selectAppropriateImage(prompt, subject),
image_max_width: 760,
caption: "<p>Visualização do conceito apresentado</p>"
});
}
// Add video if topic benefits from demonstration
if (this.shouldIncludeVideo(prompt)) {
elements.push({
id: `video-${currentId++}`,
type: "video-1",
content_title: "Vídeo Explicativo",
padding_top: 20,
padding_bottom: 20,
video: "https://www.youtube.com/embed/dQw4w9WgXcQ",
show_controls: true,
autoplay: false
});
}
return elements;
}
/**
* Generate interactive elements based on learning goals
*/
private generateInteractiveElements(prompt: string, subject: string, startId: number): CompositionElement[] {
const elements: CompositionElement[] = [];
const promptLower = prompt.toLowerCase();
let currentId = startId;
// Always include at least one interactive element
if (promptLower.includes('memoriz') || promptLower.includes('decor')) {
// Flashcards for memorization
elements.push(this.createFlashcardsElement(currentId++, prompt, subject));
}
// Quiz for assessment
elements.push(this.createQuizElement(currentId++, prompt, subject));
// Summary section
elements.push({
id: `statement-${currentId++}`,
type: "statement-1",
content_title: null,
padding_top: 35,
padding_bottom: 35,
background_color: "#E8F5E9",
primary_color: "#4CAF50",
text: "<p><strong>Parabéns!</strong> Você completou esta aula. Revise os conceitos principais e teste seus conhecimentos com as atividades propostas.</p>"
});
return elements;
}
/**
* Create flashcards element
*/
private createFlashcardsElement(id: number, prompt: string, subject: string): CompositionElement {
const topic = this.extractMainTopic(prompt);
return {
id: `flashcards-${id}`,
type: "flashcards-1",
content_title: "Cartões de Memorização",
padding_top: 35,
padding_bottom: 35,
background_color: "#FFFFFF",
card_height: 240,
card_width: 240,
border_color: "#2196F3",
items: [
{
id: "card-1",
front_card: {
text: `<p>O que é ${topic}?</p>`,
centered_image: null,
fullscreen_image: null
},
back_card: {
text: `<p>Definição e conceito principal de ${topic}</p>`,
centered_image: null,
fullscreen_image: null
},
opened: false
},
{
id: "card-2",
front_card: {
text: "<p>Características Principais</p>",
centered_image: null,
fullscreen_image: null
},
back_card: {
text: "<p>Lista das características mais importantes</p>",
centered_image: null,
fullscreen_image: null
},
opened: false
},
{
id: "card-3",
front_card: {
text: "<p>Exemplo Prático</p>",
centered_image: null,
fullscreen_image: null
},
back_card: {
text: "<p>Aplicação do conceito no dia a dia</p>",
centered_image: null,
fullscreen_image: null
},
opened: false
}
]
};
}
/**
* Create quiz element
*/
private createQuizElement(id: number, prompt: string, subject: string): CompositionElement {
const topic = this.extractMainTopic(prompt);
return {
id: `quiz-${id}`,
type: "quiz-1",
content_title: "Teste seus Conhecimentos",
padding_top: 35,
padding_bottom: 35,
background_color: "#FFFFFF",
primary_color: "#2196F3",
remake: "enable",
max_attempts: 3,
utilization: {
enabled: false,
percentage: null
},
feedback: {
type: "default"
},
questions: [
{
id: "question-1",
question: `<p>Qual a principal característica de ${topic}?</p>`,
image: null,
video: null,
answered: false,
feedback_default: { text: null, image: null, video: null, media_max_width: null },
feedback_correct: {
text: "<p><strong>Correto!</strong> Você demonstrou compreender o conceito principal.</p>",
image: null,
video: null,
media_max_width: null
},
feedback_incorrect: {
text: "<p>Revise o conteúdo para melhor compreensão do conceito.</p>",
image: null,
video: null,
media_max_width: null
},
no_correct_answer: false,
no_feedback: false,
choices: [
{
id: "choice-1",
correct: true,
text: "<p>Resposta correta sobre o conceito</p>"
},
{
id: "choice-2",
correct: false,
text: "<p>Alternativa incorreta 1</p>"
},
{
id: "choice-3",
correct: false,
text: "<p>Alternativa incorreta 2</p>"
},
{
id: "choice-4",
correct: false,
text: "<p>Alternativa incorreta 3</p>"
}
]
}
]
};
}
/**
* Helper methods
*/
private extractMainTopic(prompt: string): string {
const words = prompt.toLowerCase()
.replace(/[^\w\sàáâãéêíóôõúç]/g, ' ')
.split(' ')
.filter(word => word.length > 4);
// Common topic keywords
const topicKeywords = [
'fotossíntese', 'célula', 'sistema', 'solar', 'fração',
'equação', 'geometria', 'história', 'geografia', 'português'
];
for (const keyword of topicKeywords) {
if (prompt.toLowerCase().includes(keyword)) {
return keyword.charAt(0).toUpperCase() + keyword.slice(1);
}
}
return words[0] ? words[0].charAt(0).toUpperCase() + words[0].slice(1) : 'Conceito';
}
private generateTags(prompt: string, subject: string): string[] {
const tags = [subject.toLowerCase(), 'educação', 'interativo'];
const words = prompt.toLowerCase().split(' ');
words.forEach(word => {
if (word.length > 5 && !tags.includes(word)) {
tags.push(word);
}
});
return tags.slice(0, 6);
}
private estimateDuration(elements: CompositionElement[]): string {
const baseTime = 15; // Base time in minutes
const timePerElement = 3; // Additional time per element
const totalTime = baseTime + (elements.length * timePerElement);
return `${totalTime} minutos`;
}
private generateMainContent(prompt: string, subject: string): string {
const topic = this.extractMainTopic(prompt);
return `
<h3>Conceito Principal</h3>
<p>O estudo de <strong>${topic}</strong> é fundamental para compreender ${subject}.
Este conteúdo foi preparado para facilitar seu aprendizado através de explicações claras e exemplos práticos.</p>
<h3>Pontos Importantes</h3>
<p>Durante esta aula, vamos abordar:</p>
<ol>
<li>Definição e características principais</li>
<li>Como funciona na prática</li>
<li>Exemplos do cotidiano</li>
<li>Aplicações e importância</li>
</ol>
<h3>Vamos Aprofundar</h3>
<p>Agora que você já conhece os conceitos básicos, vamos explorar mais detalhes sobre ${topic}.
Preste atenção nos exemplos e nas atividades interativas que preparamos para você.</p>`;
}
private shouldIncludeVisuals(prompt: string): boolean {
const visualKeywords = ['diagrama', 'imagem', 'foto', 'visual', 'mostrar', 'ver'];
return visualKeywords.some(keyword => prompt.toLowerCase().includes(keyword));
}
private shouldIncludeVideo(prompt: string): boolean {
const videoKeywords = ['vídeo', 'video', 'demonstr', 'experimento', 'processo'];
return videoKeywords.some(keyword => prompt.toLowerCase().includes(keyword));
}
private selectAppropriateImage(prompt: string, subject: string): string {
// Use appropriate stock images based on subject
const subjectImages: Record<string, string> = {
'ciências': 'https://images.unsplash.com/photo-1532094349884-543bc11b234d?w=760',
'matemática': 'https://images.unsplash.com/photo-1509228468518-180dd4864904?w=760',
'português': 'https://images.unsplash.com/photo-1457369804613-52c61a468e7d?w=760',
'história': 'https://images.unsplash.com/photo-1604580864964-0462f5d5b1a8?w=760',
'geografia': 'https://images.unsplash.com/photo-1526778548025-fa2f459cd5c1?w=760'
};
return subjectImages[subject.toLowerCase()] || 'https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=760';
}
}