evaluate this app:     <script>
        const API_CACHE = new Map();
        const CACHE_DURATION = 1000 * 60 * 60; // 1 hour

        async function cachedApiCall(endpoint, params) {
            const cacheKey = JSON.stringify({endpoint, params});
            const cached = API_CACHE.get(cacheKey);
            
            if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
                return cached.data;
            }
            
            try {
                const response = await fetch(endpoint, params);
                if (!response.ok) throw new Error(`API Error: ${response.status}`);
                const data = await response.json();
                
                API_CACHE.set(cacheKey, {
                    timestamp: Date.now(),
                    data
                });
                
                return data;
            } catch (error) {
                console.error('API Error:', error);
                return cached?.data || null;
            }
        }

        function sanitizeInput(input) {
            return input.replace(/[<>]/g, '').trim().substring(0, 500);
        }

        function moderateContent(text) {
            const profanityList = ['badword1', 'badword2'];
            const lowercaseText = text.toLowerCase();
            const hasProfanity = profanityList.some(word => lowercaseText.includes(word));
            if (hasProfanity) {
                return false;
            }
            if ((text.match(/[^a-zA-Z0-9\s]/g) || []).length > text.length * 0.3) {
                return false;
            }
            return true;
        }

        async function generatePollinationsText(prompt) {
            try {
                const response = await fetch('https://text.pollinations.ai/', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        messages: [
                            { role: 'system', content: 'You are a mystery story generator creating engaging and clever narratives.' },
                            { role: 'user', content: prompt }
                        ],
                        seed: Math.floor(Math.random() * 1000),
                        model: 'openai'
                    })
                });
                
                if (!response.ok) {
                    throw new Error(`API responded with status: ${response.status}`);
                }
                
                const data = await response.json();
                return data?.choices?.[0]?.message?.content || "A mysterious occurrence has been detected...";
            } catch (error) {
                console.error('Error generating text:', error);
                alert('Failed to generate story content. Using fallback.');
                return "A mysterious occurrence has been detected...";
            }
        }

        async function generatePollinationsImage(prompt) {
            try {
                const baseImageUrl = `https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}`;
                return {
                    small: `${baseImageUrl}?width=400`,
                    medium: `${baseImageUrl}?width=800`,
                    large: `${baseImageUrl}?width=1200`
                };
            } catch (error) {
                console.error('Error generating image:', error);
                return null;
            }
        }

        let currentStory = {
            title: "No Active Investigation",
            branches: {},
            image: null
        };
        let storyState = {
            progress: 0,
            discoveredClues: [],
            currentBranch: 'start',
            variables: {},
            suspects: [],
            evidenceFound: [],
            relationships: {},
            aiAnalysis: [],
            playerTheories: []
        };

        const DIFFICULTY_LEVELS = {
            easy: {
                clueRevealRate: 0.8,
                redHerringRate: 0.2,
                timeLimit: 0 // No time limit
            },
            medium: {
                clueRevealRate: 0.6,
                redHerringRate: 0.4,
                timeLimit: 1800 // 30 minutes
            },
            hard: {
                clueRevealRate: 0.4,
                redHerringRate: 0.6,
                timeLimit: 900 // 15 minutes
            }
        };

        function setDifficulty(level) {
            // Implementation for setting difficulty
        }

        async function generateMystery() {
            const location = sanitizeInput(document.getElementById('location')?.value || 'abandoned laboratory');
            const time = sanitizeInput(document.getElementById('time')?.value || 'present day');
            const object = sanitizeInput(document.getElementById('object')?.value || 'mysterious device');  
            const suspect = sanitizeInput(document.getElementById('suspect')?.value || 'unknown scientist');
            const motive = sanitizeInput(document.getElementById('motive')?.value || 'unknown');
            const witness = sanitizeInput(document.getElementById('witness')?.value || 'anonymous source');

            if (![location, time, object, suspect, motive, witness].every(moderateContent)) {
                alert('Please keep content appropriate and family-friendly');
                return;
            }

            if (!location || !time || !object || !suspect || !motive || !witness) {
                alert('Please fill in all fields');
                return;
            }

            const storyPrompt = `Write a mystery story about a ${object} discovered at ${location} during ${time}. 
                        The main suspect is ${suspect} with a possible motive of ${motive}. 
                        A key witness, ${witness}, may hold crucial information.`;
    
            const generatedStory = await generatePollinationsText(storyPrompt);

            const imagePrompt = `mysterious scene of ${object} at ${location}, ${time} period, cinematic, dramatic lighting`;
            const mysteryImage = await generatePollinationsImage(imagePrompt);

            currentStory = {
                title: `The Mystery of the ${object} at ${location}`,
                image: mysteryImage,
                branches: {
                    start: {
                        text: generatedStory || `During ${time}, a ${object} was discovered at ${location}. The suspect ${suspect} appears to be motivated by ${motive}, while ${witness} claims to have vital information.`,
                        choices: [
                            { text: `Investigate the ${location}`, nextBranch: 'location_search' },
                            { text: `Interview ${witness}`, nextBranch: 'witness_interview' },
                            { text: `Research about ${suspect}`, nextBranch: 'suspect_background' },
                            { text: `Analyze the ${object}`, nextBranch: 'object_analysis' },
                            { text: `Investigate ${motive}`, nextBranch: 'motive_analysis' }
                        ]
                    },

                    location_search: {
                        text: `At ${location}, you find unusual energy readings and strange markings.`,
                        choices: [
                            { text: "Follow the energy trail", nextBranch: 'energy_trail' },
                            { text: "Decode the markings", nextBranch: 'markings' }
                        ]
                    },
                    suspect_background: {
                        text: `Research reveals ${suspect} was involved in classified experiments.`,
                        choices: [
                            { text: "Track recent movements", nextBranch: 'tracking' },
                            { text: "Interview colleagues", nextBranch: 'interviews' }
                        ]
                    },
                    object_analysis: {
                        text: `The ${object} appears to be emitting quantum signatures.`,
                        choices: [
                            { text: "Run detailed scan", nextBranch: 'scanning' },
                            { text: "Search for similar devices", nextBranch: 'comparison' }
                        ]
                    }
                }
            };

            storyState.currentBranch = 'start';
            updateStoryDisplay();
        }

        function updateStoryDisplay() {
            if (!currentStory || !currentStory.branches || !storyState.currentBranch || !currentStory.branches[storyState.currentBranch]) {
                const choicesDiv = document.getElementById('story-choices');
                choicesDiv.innerHTML = `
                    <div class="evidence-card">
                        <p>Use the generator above to start a new mystery investigation.</p>
                    </div>
                `;
                return;
            }

            const branch = currentStory.branches[storyState.currentBranch];
            const choicesDiv = document.getElementById('story-choices');
            choicesDiv.innerHTML = `
                ${currentStory.image ? `
                <div class="evidence-card">
                    <img srcset="${currentStory.image.small} 400w,
                                 ${currentStory.image.medium} 800w,
                                 ${currentStory.image.large} 1200w"
                         sizes="(max-width: 400px) 100vw,
                                (max-width: 800px) 800px,
                                1200px"
                         src="${currentStory.image.medium}" 
                         alt="AI generated scene of the mystery" 
                         width="100%" 
                         height="300"
                         style="object-fit: cover; border-radius: 4px;">
                </div>
                ` : ''}
                <div class="evidence-card">
                    <p>${branch.text}</p>
                </div>
                ${branch.choices ? branch.choices.map(choice => `
                    <div class="story-choice" onclick="makeChoice('${choice.nextBranch}')">
                        ${choice.text}
                    </div>
                `).join('') : ''}
            `;
        }

        function addEvidenceCard(evidence) {
            const type = evidence.type || 'physical';
            const typeData = EVIDENCE_TYPES[type];
            
            const card = document.createElement('div');
            card.className = 'evidence-card';
            card.innerHTML = `
                <h3><i class="${typeData.icon}"></i> ${evidence.title}</h3>
                <p>${evidence.description}</p>
                <div class="evidence-tags" style="color: ${typeData.color}">
                    ${evidence.tags.map(tag => `<span class="tag">${tag}</span>`).join('')}
                </div>
                <div class="evidence-reliability">
                    Reliability: ${evidence.reliability || 'Unknown'}
                </div>
            `;
            
            document.querySelector('.investigation-board').appendChild(card);
        }

        async function generateAIResponse(input) {
            if (!input || typeof input !== 'string') {
                return "Invalid input provided for analysis";
            }

            const contextPrompt = `
                Mystery Context:
                - Current Story: ${currentStory?.title || 'No active story'}
                - Discovered Clues: ${storyState?.discoveredClues?.length || 0}
                - Current Branch: ${storyState?.currentBranch || 'start'}
                - Evidence Found: ${JSON.stringify(storyState?.evidenceFound || [])}
                
                Player Theory: ${input}
                
                Analyze this theory considering:
                1. Consistency with known evidence
                2. Logical connections
                3. Potential oversights
                4. Alternative explanations
                
                Provide a detailed but concise analysis.
            `;
            
            try {
                const response = await fetch('https://text.pollinations.ai/', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        messages: [
                            { role: 'system', content: 'You are a highly skilled detective AI analyzing complex mysteries.' },
                            { role: 'user', content: contextPrompt }
                        ],
                        seed: Math.floor(Math.random() * 1000),
                        model: 'openai'
                    })
                });
                
                if (!response.ok) {
                    throw new Error(`API responded with status: ${response.status}`);
                }
                
                const data = await response.json();
                return data?.choices?.[0]?.message?.content || "The AI is processing your theory...";
            } catch (error) {
                console.error('AI Analysis Error:', error);
                return `Unable to complete analysis: ${error.message}. Please try again later.`;
            }
        }

        async function activateAI() {
            const input = document.getElementById('theory-input');
            if (!input) {
                console.error('Theory input element not found');
                return;
            }

            const theory = sanitizeInput(input.value);
            
            if (theory.length < 3) {
                alert('Please enter a longer theory');
                return;
            }

            if (!moderateContent(theory)) {
                alert('Please keep theories appropriate and family-friendly');
                return;
            }

            // Show loading state
            const timelineEvents = document.getElementById('timeline-events');
            const loadingEvent = document.createElement('div');
            loadingEvent.className = 'timeline-event';
            loadingEvent.innerHTML = `
                <span class="classified">[AI ANALYSIS]</span>
                <p><i class="fas fa-spinner fa-spin"></i> Analyzing theory...</p>
            `;
            timelineEvents.prepend(loadingEvent);

            try {
                const aiResponse = await generateAIResponse(theory);
                loadingEvent.innerHTML = `
                    <span class="classified">[AI ANALYSIS]</span>
                    <p><i class="fas fa-brain"></i> ${aiResponse}</p>
                `;
                input.value = '';
            } catch (error) {
                console.error('Error in AI analysis:', error);
                loadingEvent.innerHTML = `
                    <span class="classified">[AI ANALYSIS ERROR]</span>
                    <p><i class="fas fa-exclamation-triangle"></i> Failed to analyze theory. Please try again.</p>
                `;
            }
        }

        document.getElementById('theory-input').addEventListener('keypress', async function(e) {
            if (e.key === 'Enter') {
                await activateAI();
            }
        });

        function addTouchSupport() {
            const interactiveElements = document.querySelectorAll('.story-choice, .evidence-card, .ai-assistant');
            
            interactiveElements.forEach(element => {
                element.addEventListener('touchstart', function(e) {
                    e.preventDefault();
                    this.style.transform = 'scale(0.98)';
                });

                element.addEventListener('touchend', function() {
                    this.style.transform = 'scale(1)';
                });
            });
        }

        document.addEventListener('DOMContentLoaded', function() {
            addTouchSupport();
        });

        function makeChoice(nextBranch) {
            if (!currentStory.branches[nextBranch]) {
                console.error('Invalid branch:', nextBranch);
                return;
            }

            // Update story state
            storyState.currentBranch = nextBranch;
            storyState.progress += 10; // Increment progress
            
            // Update story display
            updateStoryDisplay();
            
            // Add timeline event
            const timelineEvents = document.getElementById('timeline-events');
            const event = document.createElement('div');
            event.className = 'timeline-event';
            event.innerHTML = `
                <span class="classified">[CHOICE MADE]</span>
                <p>${currentStory.branches[nextBranch].text}</p>
            `;
            timelineEvents.prepend(event);

            // Update progress bar
            const progressBar = document.getElementById('progress-bar');
            if (progressBar) {
                progressBar.style.width = `${Math.min(storyState.progress, 100)}%`;
            }
        }
    </script>