// Google Opal AI - Master Mini-App Studio & 3D Poster Lab Engine v5.0 document.addEventListener('DOMContentLoaded', () => { initNavigation(); initSettings(); initPosterLab(); initMiniAppsHub(); initMiniAppBuilder(); initUgcStudio(); initInboxAI(); initHistory(); }); // --- Global Navigation --- window.switchToTab = function(tabId) { const navItems = document.querySelectorAll('.nav-item'); const tabPages = document.querySelectorAll('.tab-page'); navItems.forEach(n => { if (n.getAttribute('data-tab') === tabId) { n.classList.add('active'); } else { n.classList.remove('active'); } }); tabPages.forEach(p => { if (p.id === tabId) { p.classList.add('active'); } else { p.classList.remove('active'); } }); window.scrollTo({ top: 0, behavior: 'smooth' }); }; function initNavigation() { const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.addEventListener('click', () => { const targetTabId = item.getAttribute('data-tab'); switchToTab(targetTabId); }); }); // Language Toggle const langBtn = document.getElementById('langToggleBtn'); let currentLang = 'BN'; if (langBtn) { langBtn.addEventListener('click', () => { currentLang = currentLang === 'BN' ? 'EN' : 'BN'; langBtn.textContent = currentLang === 'BN' ? '🌐 āĻŦāĻžāĻ‚' : '🌐 EN'; }); } } window.copyText = function(elementId) { const el = document.getElementById(elementId); if (el) { const text = el.value || el.textContent || ''; navigator.clipboard.writeText(text).then(() => { alert('✅ Copied to Clipboard!'); }).catch(() => { // Fallback const ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); alert('✅ Copied to Clipboard!'); }); } }; // --- Settings & Gemini 2.0 API Engine --- function initSettings() { const apiKeyInput = document.getElementById('apiKeyInput'); const modelSelect = document.getElementById('modelSelect'); const n8nWebhookInput = document.getElementById('n8nWebhookInput'); const saveBtn = document.getElementById('saveApiKeyBtn'); const statusMsg = document.getElementById('settingsStatusMsg'); // Load saved settings const savedKey = localStorage.getItem('opal_gemini_api_key') || ''; const savedModel = localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; const savedN8n = localStorage.getItem('opal_n8n_webhook') || 'https://n8n.auraajenticai.cloud/webhook/gt-auto-post'; if (apiKeyInput) apiKeyInput.value = savedKey; if (modelSelect) modelSelect.value = savedModel; if (n8nWebhookInput) n8nWebhookInput.value = savedN8n; if (saveBtn) { saveBtn.addEventListener('click', async () => { const key = apiKeyInput.value.trim(); const model = modelSelect.value; const n8nUrl = n8nWebhookInput ? n8nWebhookInput.value.trim() : ''; if (n8nUrl) { localStorage.setItem('opal_n8n_webhook', n8nUrl); } if (!key) { localStorage.setItem('opal_selected_model', model); statusMsg.classList.remove('hidden'); statusMsg.style.color = '#10B981'; statusMsg.textContent = '✅ Settings saved (Offline templates active).'; return; } statusMsg.classList.remove('hidden'); statusMsg.style.color = '#F472B6'; statusMsg.textContent = 'âŗ Testing Gemini 2.0 AI connection with Google...'; try { const res = await callGeminiApi(key, model, "Respond with: 'Google Opal AI Connected successfully!'"); if (res) { localStorage.setItem('opal_gemini_api_key', key); localStorage.setItem('opal_selected_model', model); statusMsg.style.color = '#10B981'; statusMsg.textContent = `✅ Verified & Active: ${res.trim()}`; } } catch (e) { statusMsg.style.color = '#EF4444'; statusMsg.textContent = `❌ Connection Error: ${e.message}`; } }); } } async function callGeminiApi(apiKey, model, prompt) { const activeModel = model || localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; const url = `https://generativelanguage.googleapis.com/v1beta/models/${activeModel}:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: prompt }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 2048 } }; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { const errData = await response.json().catch(() => ({})); throw new Error(errData?.error?.message || `HTTP ${response.status}`); } const data = await response.json(); return data?.candidates?.[0]?.content?.parts?.[0]?.text || ''; } // --- Curated Pre-Built Mini-Apps Suite (Universal E-Commerce) --- const PREBUILT_MINI_APPS = [ { id: 'gt_studio', name: '3D Commercial Poster Lab', emoji: '🎨', category: 'ecommerce', badge: '3D CANVAS', desc: 'āϝ⧇āϕ⧋āύ⧋ āĻĒāĻŖā§āϝ⧇āϰ āĻ›āĻŦāĻŋ, ā§ŠāĻĄāĻŋ āĻŽāĻžāĻ°ā§āĻŦ⧇āϞ āĻ¸ā§āĻŸā§‡āϜ āĻ“ WhatsApp QR āϏāĻš 4K āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāύ āĻĒā§‹āĻ¸ā§āϟāĻžāϰ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', steps: 'All Niches â€ĸ 3D Canvas', isPosterLab: true }, { id: 'fashion_stylist', name: 'Fashion, Saree & Panjabi Styling Closer', emoji: '👗', category: 'fashion', badge: 'FASHION', desc: 'āĻļāĻžā§œāĻŋ, āĻĨā§āϰāĻŋ-āĻĒāĻŋāϏ, āĻĒāĻžāĻžā§āϜāĻžāĻŦāĻŋ āĻŦāĻž āĻšā§āĻĄāĻŋāϰ āĻĢ⧇āĻŦā§āϰāĻŋāĻ• āĻĄāĻŋāĻŸā§‡āχāϞāϏ, āϏāĻžāχāϜ āĻ—āĻžāχāĻĄ āĻ“ āĻŽā§āϝāĻžāϚāĻŋāĻ‚ āϟāĻŋāĻĒāϏ āĻĻāĻŋā§Ÿā§‡ āϏ⧇āϞāϏ āĻ•ā§āϞ⧋āϜ āĻ•āϰ⧇āĨ¤', steps: '3 Steps â€ĸ Fashion Closer', fields: [ { id: 'field1', label: 'āĻĒā§‹āĻļāĻžāϕ⧇āϰ āύāĻžāĻŽ āĻ“ āĻĢ⧇āĻŦā§āϰāĻŋāĻ• (Dress / Saree & Fabric)', placeholder: 'e.g. āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻŽāϏāϞāĻŋāύ āϜāĻžāĻŽāĻĻāĻžāύāĻŋ āĻļāĻžā§œāĻŋ āĻ…āĻĨāĻŦāĻž āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻ•āϟāύ āĻĒāĻžāĻžā§āϜāĻžāĻŦāĻŋ' }, { id: 'field2', label: 'āϏāĻžāχāϜ, āĻ•āĻžāϞāĻžāϰ āĻ“ āĻ…āĻĢāĻžāϰ (Size / Color / Offer)', placeholder: 'e.g. āϏāĻžāχāϜ M, L, XL | āĻ•āĻžāϞāĻžāϰ: āĻŽā§‡āϰ⧁āύ | āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ā§ŗ ⧍,ā§Ēā§Ģā§Ļ (āĻĢā§āϰāĻŋ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ)' } ], promptTemplate: `You are an elite Bangladeshi Fashion Stylist and High-Converting Sales Closer. Item & Fabric: {{field1}} Details & Offer: {{field2}} Write 3 distinct ready-to-send Bengali fashion customer responses: 1. Aesthetic luxury product appreciation highlighting fabric softness, elegant drape, and premium feel. 2. Complete size guidance and direct order closure asking for delivery address and phone number. 3. 1-Click WhatsApp booking link: https://wa.me/8801712426871 with cash-on-delivery trial assurance.` }, { id: 'gadget_explainer', name: 'Smart Gadget & Electronics Feature Explainer', emoji: '⚡', category: 'electronics', badge: 'GADGETS', desc: 'āĻ¸ā§āĻŽāĻžāĻ°ā§āϟāĻ“ā§ŸāĻžāϚ, āĻ‡ā§ŸāĻžāϰāĻŦāĻžāĻĄāϏ āĻ“ āĻ—ā§āϝāĻžāĻœā§‡āĻŸā§‡āϰ āĻŦā§āϝāĻžāϟāĻžāϰāĻŋ āϞāĻžāχāĻĢ, āĻĄāĻŋāϏāĻĒā§āϞ⧇ āĻ“ ā§§ āĻŦāĻ›āϰ⧇āϰ āĻ“ā§ŸāĻžāϰ⧇āĻ¨ā§āϟāĻŋ āĻŦ⧁āĻāĻŋā§Ÿā§‡ āϏ⧇āϞāϏ āφāύ⧇āĨ¤', steps: '3 Steps â€ĸ Tech Sales', fields: [ { id: 'field1', label: 'āĻ—ā§āϝāĻžāĻœā§‡āĻŸā§‡āϰ āύāĻžāĻŽ āĻ“ āĻŽāĻĄā§‡āϞ (Gadget Name & Model)', placeholder: 'e.g. Ultra 9 Max Smartwatch AMOLED Display' }, { id: 'field2', label: 'āĻĢāĻŋāϚāĻžāϰ āĻ“ āĻ“ā§ŸāĻžāϰ⧇āĻ¨ā§āϟāĻŋ āĻ…āĻĢāĻžāϰ (Specs & Warranty)', placeholder: 'e.g. ā§­ āĻĻāĻŋāύ⧇āϰ āĻŦā§āϝāĻžāϟāĻžāϰāĻŋ, āĻ“ā§ŸāĻžāϟāĻžāϰāĻĒā§āϰ⧁āĻĢ IP68, ā§§ āĻŦāĻ›āϰ āϰāĻŋāĻĒā§āϞ⧇āϏāĻŽā§‡āĻ¨ā§āϟ āĻ“ā§ŸāĻžāϰ⧇āĻ¨ā§āϟāĻŋ, āĻĻāĻžāĻŽ ā§ŗ ⧍,ā§Šā§Ģā§Ļ' } ], promptTemplate: `You are a tech-savvy gadget sales expert in Bangladesh. Gadget Model: {{field1}} Specs & Offer: {{field2}} Generate 3 high-trust Bengali customer responses: 1. Power-packed feature breakdown (battery, AMOLED screen, sound quality, water resistance). 2. Official warranty guarantee & risk-free Cash on Delivery verification guide. 3. Fast 1-Click WhatsApp purchase link: https://wa.me/8801712426871.` }, { id: 'organic_honey_lab', name: 'Pure Organic Food & Honey Authenticity AI', emoji: 'đŸ¯', category: 'organic', badge: 'ORGANIC', desc: 'āϏ⧁āĻ¨ā§āĻĻāϰāĻŦāύ⧇āϰ āĻ–āĻžāρāϟāĻŋ āĻŽāϧ⧁, āϏāϰāĻŋāώāĻžāϰ āϤ⧇āϞ āĻ“ āϘāĻŋāϝāĻŧ⧇āϰ ā§§ā§Ļā§Ļ% āύāĻŋāĻ°ā§āϭ⧇āϜāĻžāϞ āĻĒā§āϰāĻŽāĻžāĻŖ āĻ“ āĻ¸ā§āĻŦāĻžāĻ¸ā§āĻĨā§āϝ āωāĻĒāĻ•āĻžāϰāĻŋāϤāĻž āϜāĻžāύāĻžā§ŸāĨ¤', steps: '3 Steps â€ĸ Pure Food', fields: [ { id: 'field1', label: 'āĻĒāĻŖā§āϝ⧇āϰ āύāĻžāĻŽ āĻ“ āĻ‰ā§ŽāϏ (Organic Food & Source)', placeholder: 'e.g. āϏ⧁āĻ¨ā§āĻĻāϰāĻŦāύ⧇āϰ āĻĒā§āϰāĻžāĻ•ā§ƒāϤāĻŋāĻ• āϚāĻžāϕ⧇āϰ āĻ–āĻžāρāϟāĻŋ āĻŽāϧ⧁ (ā§§ āϕ⧇āϜāĻŋ)' }, { id: 'field2', label: 'āωāĻĒāĻ•āĻžāϰāĻŋāϤāĻž āĻ“ āĻŽā§‚āĻ˛ā§āϝ (Benefits & Price)', placeholder: 'e.g. ā§§ā§Ļā§Ļ% āĻ˛ā§āϝāĻžāĻŦ āĻŸā§‡āĻ¸ā§āĻŸā§‡āĻĄ, āϰ⧋āĻ— āĻĒā§āϰāϤāĻŋāϰ⧋āϧ āĻ•ā§āώāĻŽāϤāĻž āĻŦāĻžā§œāĻžā§Ÿ, āĻĻāĻžāĻŽ ā§ŗ ā§§,⧍ā§Ļā§Ļ' } ], promptTemplate: `You are a trusted organic food & wellness advisor in Bangladesh. Product: {{field1}} Benefits & Price: {{field2}} Write 3 persuasive, trust-building Bengali customer messages: 1. Purity assurance (lab-tested, unadulterated, raw natural honey/ghee taste). 2. Health & wellness benefits for family/children. 3. Cash-on-Delivery order confirmation with tasting guarantee upon courier arrival.` }, { id: 'sneaker_style_hub', name: 'Sneaker Legit Check & Footwear Closer', emoji: '👟', category: 'footwear', badge: 'SNEAKERS', desc: 'āĻ¸ā§āύāĻŋāĻ•āĻžāϰ, āϞ⧋āĻĢāĻžāϰ āĻ“ āϚāĻžāĻŽā§œāĻžāϰ āϜ⧁āϤāĻžāϰ āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ, āϕ⧁āĻļāύ āĻ•āĻŽāĻĢā§‹āĻ°ā§āϟ āĻ“ āϏāĻžāχāϜ āĻŸā§āϰāĻžā§ŸāĻžāϞ āĻŦ⧁āĻāĻžā§ŸāĨ¤', steps: '3 Steps â€ĸ Footwear', fields: [ { id: 'field1', label: 'āϜ⧁āϤāĻžāϰ āύāĻžāĻŽ āĻ“ āĻŽā§‡āĻŸā§‡āϰāĻŋ⧟āĻžāϞ (Shoe / Sneaker Model)', placeholder: 'e.g. Air Jordan Retro High OG / Pure Cow Leather Loafer' }, { id: 'field2', label: 'āϏāĻžāχāϜ āĻ“ āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ (Size Chart & Offer)', placeholder: 'e.g. āϏāĻžāχāϜ ā§Šā§¯ āĻĨ⧇āϕ⧇ ā§Ēā§Ē | āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻĢā§‹āĻŽ āχāύāϏ⧋āϞ | āĻĻāĻžāĻŽ ā§ŗ ⧍,ā§Žā§Ģā§Ļ' } ], promptTemplate: `You are a street-style sneakerhead and footwear closer in Bangladesh. Model: {{field1}} Details: {{field2}} Create 3 urban, stylish Bengali customer messages: 1. Comfort, sole durability, and stylish outfit pairing tips. 2. Hassle-free size exchange guarantee with cash on delivery. 3. Fast WhatsApp order link with doorstep fitting check.` }, { id: 'inbox_ai', name: 'Customer Care & Universal Sales Closer', emoji: 'đŸ’Ŧ', category: 'sales', badge: 'AI CLOSER', desc: 'āĻĢ⧇āϏāĻŦ⧁āĻ• āĻ“ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇āϰ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĒā§āϰāĻļā§āύ⧇āϰ ā§ŠāϟāĻŋ āχāύāĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āϟ āĻŽāĻŋāĻˇā§āϟāĻŋ āĻ“ āϏ⧇āϞāϏ āĻ•ā§āϞ⧋āϜāĻŋāĻ‚ āωāĻ¤ā§āϤāϰ āĻŦāĻžāύāĻžā§ŸāĨ¤', steps: '3 Steps â€ĸ Sales Closer', fields: [ { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ āĻŽā§‡āϏ⧇āϜ (Customer Message)', placeholder: 'e.g. āφāĻĒāύāĻžāĻĻ⧇āϰ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻĻāĻžāĻŽ āĻ•āϤ āφāϰ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āϚāĻžāĻ°ā§āϜ āĻ•āϤ?' }, { id: 'field2', label: 'āĻĻā§‹āĻ•āĻžāύ⧇āϰ āĻ…āĻĢāĻžāϰ āĻŦāĻž āĻšāϟāϞāĻžāχāύ (Store Context)', placeholder: 'e.g. āĻĻāĻžāĻŽ ā§§,ā§Ēā§Ģā§Ļ āϟāĻžāĻ•āĻž, āĻĸāĻžāĻ•āĻž ā§­ā§Ļ āϟāĻžāĻ•āĻž, āĻšāϟāϞāĻžāχāύ ā§Ļ⧧⧭⧧⧍-ā§Ē⧍ā§Ŧā§Žā§­ā§§' } ], promptTemplate: `You are an expert Bangladeshi e-commerce sales closer. Customer message: {{field1}} Store context: {{field2}} Write 3 distinct ready-to-copy Bengali replies: 1. Instant sweet greeting with price & benefits 2. Direct order closing script asking for Name, Address, Phone 3. 1-Click WhatsApp direct order message with link https://wa.me/8801712426871` }, { id: 'veo_prompter', name: 'Google Veo 3.1 & Omni Video Prompter', emoji: 'đŸŽŦ', category: 'social', badge: 'VEO 3.1', desc: 'āϏāĻ•āϞ āĻ•ā§āϝāĻžāϟāĻžāĻ—āϰāĻŋāϰ āĻĒāĻŖā§āϝ⧇āϰ āϜāĻ¨ā§āϝ āϏāĻŋāύ⧇āĻŽāĻžāϟāĻŋāĻ• 9:16 āĻ­āĻŋāĻĄāĻŋāĻ“ āĻĒā§āϰāĻŽā§āĻĒāϟ, āĻ•ā§āϝāĻžāĻŽā§‡āϰāĻž āĻŽā§‹āĻļāύ āĻ“ āϞāĻžāχāϟāĻŋāĻ‚ āĻ—āĻžāχāĻĄ āĻŦāĻžāύāĻžā§ŸāĨ¤', steps: '4 Steps â€ĸ AI Video', fields: [ { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āύāĻžāĻŽ āĻ“ āϧāϰāĻŖ (Product & Category)', placeholder: 'e.g. Silk Saree / Smartwatch / Pure Honey / Face Serum' }, { id: 'field2', label: 'āĻ­āĻŋāĻĄāĻŋāĻ“āϰ āĻ­āĻžāχāĻŦ āĻ“ āĻ¸ā§āϟāĻžāχāϞ (Style / Lighting)', placeholder: 'e.g. Cinematic Studio, Macro slow-mo, neon rim light, 4K raytraced' } ], promptTemplate: `You are a world-class AI Video Prompt Engineer for Google Veo 3.1 and Sora. Create an ultra-detailed, cinematic 9:16 vertical video prompt for: Product: {{field1}} Style/Vibe: {{field2}} Include: 1. Master Cinematic Prompt (in English for AI video model) 2. Camera Movements (Macro close-up, 360 rotation, slow motion reveal) 3. Studio Lighting & Physics (Softbox, rim lighting, atmospheric particles) 4. Bengali Narration / Voiceover Script (15 seconds)` }, { id: 'risk_scorer', name: 'Gemini COD Fraud & Return Risk Shield', emoji: 'đŸ›Ąī¸', category: 'tools', badge: 'AI SHIELD', desc: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĢā§‹āύ āύāĻžāĻŽā§āĻŦāĻžāϰ, āĻ āĻŋāĻ•āĻžāύāĻž āĻ“ āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻŦāĻŋāĻļā§āϞ⧇āώāĻŖ āĻ•āϰ⧇ āϰāĻŋāϟāĻžāĻ°ā§āύ āĻĢā§āϰāĻĄ āϰāĻŋāĻ¸ā§āĻ• āĻ¸ā§āϕ⧋āϰ āĻĻā§‡ā§ŸāĨ¤', steps: 'Real-time â€ĸ Gemini 2.0', fields: [ { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻĢā§‹āύ āύāĻžāĻŽā§āĻŦāĻžāϰ (Phone Number)', placeholder: 'e.g. 01819998877' }, { id: 'field2', label: 'āĻ āĻŋāĻ•āĻžāύāĻž āĻ“ āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻŽā§‚āĻ˛ā§āϝ (Address & Amount)', placeholder: 'e.g. Mirpur 10, Dhaka - Amount: ā§ŗ 3,200' } ], promptTemplate: `You are an advanced e-commerce Fraud Risk Analysis Engine for Bangladesh logistics. Phone: {{field1}} Order Info: {{field2}} Evaluate: 1. Risk Level: (LOW / MEDIUM / HIGH) 2. Recommendation: (Proceed with COD / Take Advance Delivery Charge ā§ŗ150 / Call to verify) 3. Short reasoning in clear Bengali.` }, { id: 'ecommerce_launch', name: 'E-Commerce Viral Product Launch Kit', emoji: 'đŸ›ī¸', category: 'ecommerce', badge: 'VIRAL', desc: 'āϝ⧇āϕ⧋āύ⧋ āĻĒāĻŖā§āϝ⧇āϰ āφāĻ•āĻ°ā§āώāĻŖā§€ā§Ÿ āĻĢ⧇āϏāĻŦ⧁āĻ• āĻĒā§‹āĻ¸ā§āϟ āĻ•ā§āϝāĻžāĻĒāĻļāύ, āĻĒ⧇āχāύ āĻĒā§Ÿā§‡āĻ¨ā§āϟ āĻšā§āĻ• āĻ“ āĻ…āĻĢāĻžāϰ āĻ•āĻĒāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', steps: '5 Steps â€ĸ Marketing', fields: [ { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āύāĻžāĻŽ āĻ“ āĻ•ā§āϝāĻžāϟāĻžāĻ—āϰāĻŋ (Product Name & Niche)', placeholder: 'e.g. Luxury Silk Saree / Wireless ANC Earbuds / Pure Honey' }, { id: 'field2', label: 'āĻŽā§‚āϞ āϏ⧁āĻŦāĻŋāϧāĻž āĻ“ āĻ…āĻĢāĻžāϰ (Key Benefits & Offer)', placeholder: 'e.g. āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ, ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ, ⧍ā§Ģ% āĻĄāĻŋāϏāĻ•āĻžāωāĻ¨ā§āϟ' } ], promptTemplate: `You are a high-converting Facebook ad copywriter in Bangladesh. Create a complete viral product launch post in attractive Bengali for: Product: {{field1}} Benefits & Offer: {{field2}} Format: - 3 Viral Opening Hooks (Emoji heavy) - Problem & Solution story - Special Limited Time Offer & Delivery Info - Urgent Call-to-Action with WhatsApp & Website link` }, { id: 'tiktok_hooks', name: 'TikTok & Meta Reels Viral Hook Matrix', emoji: 'đŸ”Ĩ', category: 'social', badge: 'HOOKS', desc: 'āĻĒā§āϰāĻĨāĻŽ ā§Š āϏ⧇āϕ⧇āĻ¨ā§āĻĄā§‡ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āĻšā§‹āĻ– āφāϟāϕ⧇ āĻĢ⧇āϞāĻžāϰ āĻŽāϤ⧋ ā§ĢāϟāĻŋ āϏāĻžāχāϕ⧋āϞāϜāĻŋāĻ•ā§āϝāĻžāϞ āĻ­āĻžāχāϰāĻžāϞ āĻšā§āĻ• āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', steps: '5 Viral Hooks â€ĸ Reels', fields: [ { id: 'field1', label: 'āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟ āĻŦāĻž āĻŦāĻŋāĻˇā§Ÿā§‡āϰ āύāĻžāĻŽ (Product / Topic)', placeholder: 'e.g. Smart Watch / Designer Saree / Organic Honey / Leather Shoe' }, { id: 'field2', label: 'āϟāĻžāĻ°ā§āϗ⧇āϟ āĻ…āĻĄāĻŋā§Ÿā§‡āĻ¨ā§āϏ (Target Audience)', placeholder: 'e.g. āĻĢā§āϝāĻžāĻļāύ āϏāĻšā§‡āϤāύ āϤāϰ⧁āĻŖ-āϤāϰ⧁āĻŖā§€ āĻŦāĻž āĻ—ā§āϝāĻžāĻœā§‡āϟ āϞāĻžāĻ­āĻžāϰ' } ], promptTemplate: `You are a viral TikTok & Instagram Reels growth strategist. Create 5 powerful 3-second visual + verbal hooks in Bengali for: Product: {{field1}} Target Audience: {{field2}} Format each hook with: - Visual Action (Screen text & actor action) - Spoken Audio Hook (High curiosity / urgency) - Psychology trigger explanation` }, { id: 'urgency_sales', name: 'Flash Sale & Urgency Campaign Copywriter', emoji: 'đŸˇī¸', category: 'sales', badge: 'OFFER', desc: '⧍ā§Ē āϘāĻŖā§āϟāĻžāϰ āĻĢā§āĻ˛ā§āϝāĻžāĻļ āϏ⧇āϞ, āĻ¸ā§āϟāĻ• āĻ•ā§āϞāĻŋ⧟āĻžāϰ⧇āĻ¨ā§āϏ āĻ“ āψāĻĻ/āĻŦ⧈āĻļāĻžāĻ–ā§€ āĻ…āĻĢāĻžāϰ⧇āϰ āĻšāĻžāχ-āĻ•āύāĻ­āĻžāĻ°ā§āϟāĻŋāĻ‚ āĻ•āĻĒāĻŋ āĻŦāĻžāύāĻžā§ŸāĨ¤', steps: 'Flash Sales â€ĸ Copy', fields: [ { id: 'field1', label: 'āĻ…āĻĢāĻžāϰ⧇āϰ āύāĻžāĻŽ āĻ“ āĻĄāĻŋāϏāĻ•āĻžāωāĻ¨ā§āϟ (Offer Details)', placeholder: 'e.g. 48 Hours Weekend Flash Sale - Flat 35% OFF' }, { id: 'field2', label: 'āĻļāĻ°ā§āϤ āĻ“ āĻĢā§āϰāĻŋ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ (Conditions & Perks)', placeholder: 'e.g. āĻĒā§āϰāĻĨāĻŽ ā§Ģā§Ļ āϜāύ⧇āϰ āϜāĻ¨ā§āϝ āĻĢā§āϰāĻŋ āĻ—āĻŋāĻĢāϟ āĻ“ āĻĢā§āϰāĻŋ āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ' } ], promptTemplate: `Create an irresistible, high-urgency Flash Sale ad copy in natural Bengali for: Campaign: {{field1}} Perks: {{field2}} Include FOMO triggers, countdown psychological anchors, and clear WhatsApp booking steps.` }, { id: 'courier_formatter', name: 'Steadfast & Pathao Consignment Formatter', emoji: 'đŸ“Ļ', category: 'tools', badge: 'LOGISTICS', desc: 'āĻ…āĻ°ā§āĻĄāĻžāϰ⧇āϰ āĻŸā§‡āĻ•ā§āϏāϟ āĻĨ⧇āϕ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ āϕ⧁āϰāĻŋ⧟āĻžāϰ āĻāĻ¨ā§āĻŸā§āϰāĻŋ āĻĢāϰāĻŽā§āϝāĻžāϟ āĻ“ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āϞ⧇āĻŦ⧇āϞ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĨ¤', steps: '1-Click â€ĸ Logistics', fields: [ { id: 'field1', label: 'āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ⧇āϰ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻŸā§‡āĻ•ā§āϏāϟ (Order Text)', placeholder: 'e.g. āύāĻžāĻŽ: āϤāĻžāύāĻ­ā§€āϰ āĻšāĻžāϏāĻžāύ, āĻĢā§‹āύ: 01712345678, āĻ āĻŋāĻ•āĻžāύāĻž: āĻŦāĻžā§œāĻŋ ⧧⧍, āϰ⧋āĻĄ ā§Ģ, āϧāĻžāύāĻŽāĻ¨ā§āĻĄāĻŋ, āĻĸāĻžāĻ•āĻžāĨ¤ āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟ: ā§§ āĻĒāĻŋāϏ āĻ—ā§āϝāĻžāĻœā§‡āϟ (ā§ŗā§§ā§Žā§Ģā§Ļ)' }, { id: 'field2', label: 'āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āϚāĻžāĻ°ā§āϜ āĻ“ āύ⧋āϟ (COD & Notes)', placeholder: 'e.g. COD Amount: ā§ŗ 1920 (Dhaka inside ā§ŗ70)' } ], promptTemplate: `Parse this customer order and structure it cleanly for Steadfast / Pathao Courier API and Print Packing Sticker: Order Text: {{field1}} COD Info: {{field2}} Generate: 1. Structured CSV/JSON Format (Name, Phone, Address, COD, Instruction) 2. Clean Printable Packing Slip in Bengali.` } ]; // --- Mini-Apps Hub Logic --- let activeCategory = 'all'; function initMiniAppsHub() { renderMiniApps(); const filterChips = document.querySelectorAll('.filter-chip'); filterChips.forEach(chip => { chip.addEventListener('click', () => { filterChips.forEach(c => c.classList.remove('active')); chip.classList.add('active'); activeCategory = chip.getAttribute('data-cat'); renderMiniApps(); }); }); } function getCustomMiniApps() { return JSON.parse(localStorage.getItem('opal_custom_apps') || '[]'); } function renderMiniApps() { const container = document.getElementById('appsGridContainer'); if (!container) return; const customApps = getCustomMiniApps(); const allApps = [...PREBUILT_MINI_APPS, ...customApps]; const filtered = activeCategory === 'all' ? allApps : (activeCategory === 'custom' ? customApps : allApps.filter(a => a.category === activeCategory)); if (filtered.length === 0) { container.innerHTML = `
📭

No mini-apps found in this category. Click "+ Create App" to build one!

`; return; } container.innerHTML = filtered.map(app => `
${app.emoji || '💎'}
${app.badge || 'CUSTOM'}

${app.name}

${app.desc || 'AI powered dynamic mini-app for client dashboard.'}

`).join(''); } // --- Visual Mini-App Builder --- function initMiniAppBuilder() { const nameInput = document.getElementById('builderAppName'); const emojiInput = document.getElementById('builderAppEmoji'); const catSelect = document.getElementById('builderCategory'); const modelSelect = document.getElementById('builderModel'); const descInput = document.getElementById('builderDesc'); const f1Input = document.getElementById('builderField1'); const f2Input = document.getElementById('builderField2'); const templateInput = document.getElementById('builderPromptTemplate'); const saveBtn = document.getElementById('saveMiniAppBtn'); const testBtn = document.getElementById('testMiniAppBtn'); const statusMsg = document.getElementById('builderStatusMsg'); if (!saveBtn) return; saveBtn.addEventListener('click', () => { const name = nameInput.value.trim(); if (!name) { alert('Please enter a Mini-App name'); return; } const newApp = { id: 'custom_' + Date.now(), name: name, emoji: emojiInput.value.trim() || '💎', category: catSelect.value, model: modelSelect.value, badge: 'CUSTOM APP', desc: descInput.value.trim() || 'Custom client dashboard mini-app.', steps: 'Custom â€ĸ Gemini AI', fields: [ { id: 'field1', label: f1Input.value.trim() || 'Field 1', placeholder: 'Enter ' + (f1Input.value.trim() || 'Field 1') }, { id: 'field2', label: f2Input.value.trim() || 'Field 2', placeholder: 'Enter ' + (f2Input.value.trim() || 'Field 2') } ], promptTemplate: templateInput.value.trim(), createdAt: new Date().toISOString() }; const existing = getCustomMiniApps(); existing.unshift(newApp); localStorage.setItem('opal_custom_apps', JSON.stringify(existing)); statusMsg.classList.remove('hidden'); statusMsg.style.color = '#10B981'; statusMsg.textContent = `🎉 Mini-App "${name}" successfully saved & added to Hub!`; renderMiniApps(); setTimeout(() => { switchToTab('tabApps'); statusMsg.classList.add('hidden'); }, 1200); }); if (testBtn) { testBtn.addEventListener('click', () => { const name = nameInput.value.trim() || 'Test Mini-App'; const tempApp = { id: 'test_temp', name: name, emoji: emojiInput.value.trim() || 'đŸ§Ē', desc: descInput.value.trim() || 'Testing custom app runner', fields: [ { id: 'field1', label: f1Input.value.trim() || 'Field 1', placeholder: 'Input 1' }, { id: 'field2', label: f2Input.value.trim() || 'Field 2', placeholder: 'Input 2' } ], promptTemplate: templateInput.value.trim(), model: modelSelect.value }; launchRunnerWithApp(tempApp); }); } } // --- Interactive Mini-App Runner (Modal) --- let currentRunningApp = null; window.openAppRunner = function(appId) { if (appId === 'gt_studio') { switchToTab('tabPosterLab'); return; } if (appId === 'inbox_ai') { switchToTab('tabInboxAI'); return; } const allApps = [...PREBUILT_MINI_APPS, ...getCustomMiniApps()]; const app = allApps.find(a => a.id === appId); if (!app) return; launchRunnerWithApp(app); }; function launchRunnerWithApp(app) { currentRunningApp = app; const modal = document.getElementById('appRunnerModal'); const title = document.getElementById('runnerModalTitle'); const desc = document.getElementById('runnerModalDesc'); const formBox = document.getElementById('runnerDynamicForm'); const resultBox = document.getElementById('runnerResultBox'); const statusMsg = document.getElementById('runnerStatusMsg'); title.innerHTML = `${app.emoji || '🚀'} ${app.name}`; desc.textContent = app.desc || ''; resultBox.classList.add('hidden'); statusMsg.classList.add('hidden'); const fields = app.fields || [ { id: 'field1', label: 'Input 1', placeholder: 'Enter details...' }, { id: 'field2', label: 'Input 2', placeholder: 'Enter additional context...' } ]; formBox.innerHTML = fields.map((f, i) => `
`).join(''); modal.classList.remove('hidden'); } window.closeAppRunner = function() { document.getElementById('appRunnerModal').classList.add('hidden'); currentRunningApp = null; }; // Handle Mini-App Execution document.addEventListener('DOMContentLoaded', () => { const execBtn = document.getElementById('runnerExecuteBtn'); if (execBtn) { execBtn.addEventListener('click', async () => { if (!currentRunningApp) return; const statusMsg = document.getElementById('runnerStatusMsg'); const resultBox = document.getElementById('runnerResultBox'); const resultContent = document.getElementById('runnerResultContent'); statusMsg.classList.remove('hidden'); statusMsg.style.color = '#C084FC'; statusMsg.textContent = 'âŗ Processing with Google Gemini 2.0 AI...'; execBtn.disabled = true; // Extract form values const inputs = document.querySelectorAll('.runner-input'); let prompt = currentRunningApp.promptTemplate || 'Generate helpful response for the user.'; inputs.forEach(input => { const varName = input.getAttribute('data-var'); const val = input.value.trim() || 'N/A'; const regex = new RegExp(`{{${varName}}}`, 'g'); prompt = prompt.replace(regex, val); }); const apiKey = localStorage.getItem('opal_gemini_api_key') || ''; const model = currentRunningApp.model || localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; try { let output = ''; if (apiKey) { output = await callGeminiApi(apiKey, model, prompt); } else { // Dynamic intelligent fallback output = `✨ [Google Opal AI Offline Mode]\n\n` + `Generated Output for: ${currentRunningApp.name}\n` + `----------------------------------------\n` + `ā§§. āĻ…āĻĢāĻžāϰ āĻ“ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ āϰ⧇āϏāĻĒāĻ¨ā§āϏ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤\n` + `⧍. ā§§ā§Ļā§Ļ% āĻœā§‡āύ⧁āχāύ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āĻ“ āϏ⧁āĻĒāĻžāϰāĻĢāĻžāĻ¸ā§āϟ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύāĨ¤\n` + `ā§Š. āϏāϰāĻžāϏāϰāĻŋ āϝ⧋āĻ—āĻžāϝ⧋āĻ—: https://wa.me/8801712426871\n\n` + `💡 āϟāĻŋāĻĒāϏ: Settings-āĻ āĻ—āĻŋā§Ÿā§‡ āφāĻĒāύāĻžāϰ Google Gemini API Key āĻŦāϏāĻžāϞ⧇ āϰāĻŋā§Ÿā§‡āϞ-āϟāĻžāχāĻŽ āφāύāϞāĻŋāĻŽāĻŋāĻŸā§‡āĻĄ āϞāĻžāχāĻ­ āϰ⧇āϏāĻĒāĻ¨ā§āϏ āĻĒāĻžāĻŦ⧇āύ!`; } resultContent.textContent = output.trim(); resultBox.classList.remove('hidden'); statusMsg.classList.add('hidden'); // Save to History saveGenerationToHistory({ type: currentRunningApp.name, title: currentRunningApp.name, price: 'AI Generation', date: new Date().toLocaleTimeString() }); } catch (err) { statusMsg.style.color = '#EF4444'; statusMsg.textContent = `❌ Error: ${err.message}`; } execBtn.disabled = false; }); } }); // --- 1-Click Client Dashboard Embed Modal --- window.openEmbedModal = function(appId) { const modal = document.getElementById('embedModal'); const title = document.getElementById('embedModalTitle'); const iframeBox = document.getElementById('embedIframeCode'); const apiUrlBox = document.getElementById('embedApiUrl'); const allApps = [...PREBUILT_MINI_APPS, ...getCustomMiniApps()]; const app = allApps.find(a => a.id === appId) || { name: 'Opal Mini-App', id: appId }; title.innerHTML = `đŸ“Ļ Embed "${app.name}" in Client Dashboard`; const baseUrl = 'https://opal.auraajenticai.cloud'; iframeBox.textContent = ``; apiUrlBox.textContent = `${baseUrl}/api/v1/mini-app/run?app_id=${app.id}`; modal.classList.remove('hidden'); }; window.closeEmbedModal = function() { document.getElementById('embedModal').classList.add('hidden'); }; // --- Masterpiece 3D Canvas Poster Engine --- let selectedStageTheme = 'obsidian_gold'; function initPosterLab() { const productInput = document.getElementById('productInput'); const productPrice = document.getElementById('productPrice'); const customBadgeInput = document.getElementById('customBadgeInput'); const aspectRatioSelect = document.getElementById('aspectRatioSelect'); const brandSelect = document.getElementById('brandWatermarkSelect'); const photoFileInput = document.getElementById('photoFileInput'); const clearPhotoBtn = document.getElementById('clearPhotoBtn'); const photoPreviewContainer = document.getElementById('photoPreviewContainer'); const attachedPhotoImg = document.getElementById('attachedPhotoImg'); const generatePosterBtn = document.getElementById('generatePosterBtn'); const posterStatusText = document.getElementById('posterStatusText'); const posterResultCard = document.getElementById('posterResultCard'); const posterCanvas = document.getElementById('posterCanvas'); const canvasContainer = document.getElementById('canvasContainer'); const downloadPosterBtn = document.getElementById('downloadPosterBtn'); const shareWhatsAppBtn = document.getElementById('shareWhatsAppBtn'); // Stage Theme Selector const themeChips = document.querySelectorAll('#themeSelectorGroup .theme-chip'); themeChips.forEach(chip => { chip.addEventListener('click', () => { themeChips.forEach(c => c.classList.remove('active')); chip.classList.add('active'); selectedStageTheme = chip.getAttribute('data-theme'); }); }); let attachedImageBitmap = null; // Photo Input change photoFileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (event) => { attachedPhotoImg.src = event.target.result; photoPreviewContainer.classList.remove('hidden'); clearPhotoBtn.classList.remove('hidden'); const img = new Image(); img.onload = () => { attachedImageBitmap = img; }; img.src = event.target.result; }; reader.readAsDataURL(file); } }); clearPhotoBtn.addEventListener('click', () => { photoFileInput.value = ''; attachedImageBitmap = null; photoPreviewContainer.classList.add('hidden'); clearPhotoBtn.classList.add('hidden'); }); // Generate 3D Poster generatePosterBtn.addEventListener('click', async () => { const inputVal = productInput.value.trim(); const priceVal = productPrice.value.trim(); const badgeText = customBadgeInput ? customBadgeInput.value.trim() : '🇰🇷 100% Original Korea'; const aspect = aspectRatioSelect ? aspectRatioSelect.value : '1:1'; const brand = brandSelect ? brandSelect.value : 'glamourstouch'; posterStatusText.classList.remove('hidden'); posterStatusText.style.color = '#F59E0B'; posterStatusText.textContent = 'âŗ Rendering 3D stage with GPU canvas blend...'; generatePosterBtn.disabled = true; try { let productImg = attachedImageBitmap; let title = "Authentic Korean K-Beauty Care"; if (!productImg) { const resolved = await resolveProductUrl(inputVal); if (resolved && resolved.imageUrl) { title = resolved.title || inputVal; productImg = await loadImage(resolved.imageUrl); } else { const fallbackUrl = `https://images.unsplash.com/photo-1556228720-195a672e8a03?w=800&h=800&fit=crop`; productImg = await loadImage(fallbackUrl); title = inputVal; } } if (productImg) { if (aspect === '9:16') { posterCanvas.width = 1080; posterCanvas.height = 1920; canvasContainer.classList.add('aspect-reels'); } else { posterCanvas.width = 1080; posterCanvas.height = 1080; canvasContainer.classList.remove('aspect-reels'); } await render3DCommercialPoster(posterCanvas, productImg, title, priceVal, badgeText, selectedStageTheme, aspect, brand); posterResultCard.classList.remove('hidden'); posterStatusText.classList.add('hidden'); posterResultCard.scrollIntoView({ behavior: 'smooth' }); saveGenerationToHistory({ type: '3D Poster', title: title, price: priceVal, date: new Date().toLocaleTimeString() }); } else { posterStatusText.textContent = '❌ Failed to load product image.'; } } catch (err) { posterStatusText.textContent = `❌ Error: ${err.message}`; } generatePosterBtn.disabled = false; }); // Download downloadPosterBtn.addEventListener('click', () => { const link = document.createElement('a'); link.download = `Opal_3D_Poster_${Date.now()}.jpg`; link.href = posterCanvas.toDataURL('image/jpeg', 0.95); link.click(); }); // WhatsApp shareWhatsAppBtn.addEventListener('click', () => { const text = encodeURIComponent(`✨ 100% Authentic Product Order!\nProduct: ${productInput.value}\nPrice: ${productPrice.value}\nWebsite: https://glamourstouch.com`); window.open(`https://wa.me/8801712426871?text=${text}`, '_blank'); }); // n8n Auto-Post Webhook const autoPostN8nBtn = document.getElementById('autoPostN8nBtn'); const n8nPostStatusMsg = document.getElementById('n8nPostStatusMsg'); if (autoPostN8nBtn) { autoPostN8nBtn.addEventListener('click', async () => { const webhookUrl = localStorage.getItem('opal_n8n_webhook'); if (!webhookUrl) { alert('âš ī¸ Please configure n8n Webhook URL in Settings first!'); switchToTab('tabSettings'); return; } n8nPostStatusMsg.classList.remove('hidden'); n8nPostStatusMsg.style.color = '#38BDF8'; n8nPostStatusMsg.textContent = 'âŗ Sending 3D poster & copy to n8n Webhook...'; autoPostN8nBtn.disabled = true; try { const posterDataUrl = posterCanvas.toDataURL('image/jpeg', 0.92); const payload = { title: productInput.value.trim() || 'Authentic K-Beauty Skincare', price: productPrice.value.trim() || 'ā§ŗ ā§§,ā§Ļā§Ŧā§Ļ', caption: `✨ ${productInput.value.trim()} ✨\n\n💰 āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ${productPrice.value.trim()}\nđŸ›Ąī¸ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ!\n\nđŸ’Ŧ āϏāϰāĻžāϏāϰāĻŋ WhatsApp āĻ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ:\n👉 https://wa.me/8801712426871\n📞 āĻšāϟāϞāĻžāχāύ: 01712-426871\n🌐 āĻ“ā§Ÿā§‡āĻŦāϏāĻžāχāϟ: https://glamourstouch.com`, image_url: posterDataUrl, store: "Glamour's Touch", website: "https://glamourstouch.com", whatsapp: "01712-426871", timestamp: new Date().toISOString() }; const res = await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (res.ok) { const resData = await res.json().catch(() => ({})); n8nPostStatusMsg.style.color = '#10B981'; n8nPostStatusMsg.textContent = `✅ ${resData.message || '🎉 āĻĒā§‹āĻ¸ā§āϟāϟāĻŋ āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ n8n-āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ Facebook Page-āĻ āĻĒāĻžāĻŦāϞāĻŋāĻļ āĻšā§Ÿā§‡āϛ⧇!'}`; } else { n8nPostStatusMsg.style.color = '#EF4444'; n8nPostStatusMsg.textContent = `❌ n8n Webhook returned HTTP ${res.status}`; } } catch (err) { n8nPostStatusMsg.style.color = '#EF4444'; n8nPostStatusMsg.textContent = `❌ Connection Error: ${err.message}`; } autoPostN8nBtn.disabled = false; }); } } // Universal Link Resolver async function resolveProductUrl(input) { if (!input) return null; if (input.match(/\.(jpeg|jpg|gif|png|webp)($|\?)/i)) { return { title: 'Authentic Product', imageUrl: input }; } const key = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZtY2x0cmpudXZ1b29hcmt2dWZuIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzUxMzY3MDQsImV4cCI6MjA5MDcxMjcwNH0.PkSgBAZx41X4sZurfyOdxCVa01hkKTkyBhVkGzx_4y4'; const uuidMatch = input.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/); if (uuidMatch) { try { const res = await fetch(`https://fmcltrjnuvuooarkvufn.supabase.co/rest/v1/products?id=eq.${uuidMatch[0]}&select=*`, { headers: { 'apikey': key, 'Authorization': `Bearer ${key}` } }); const data = await res.json(); if (data && data.length > 0) { const p = data[0]; return { title: p.name || 'Authentic Korean Skincare', price: p.price ? 'ā§ŗ ' + p.price : '', imageUrl: p.image || p.image_url || (p.images && p.images[0]) || '' }; } } catch (e) { console.warn('GT Supabase fetch by ID failed:', e); } } try { const cleanQuery = encodeURIComponent(input.replace(/https?:\/\/[^\s]+/g, '').trim().slice(0, 30)); if (cleanQuery) { const res = await fetch(`https://fmcltrjnuvuooarkvufn.supabase.co/rest/v1/products?name=ilike.*${cleanQuery}*&select=*&limit=1`, { headers: { 'apikey': key, 'Authorization': `Bearer ${key}` } }); const data = await res.json(); if (data && data.length > 0) { const p = data[0]; return { title: p.name || input, price: p.price ? 'ā§ŗ ' + p.price : '', imageUrl: p.image || p.image_url || (p.images && p.images[0]) || '' }; } } } catch (e) { console.warn('GT Supabase search by name failed:', e); } return { title: input, imageUrl: 'https://images.unsplash.com/photo-1556228720-195a672e8a03?w=800&h=800&fit=crop' }; } function loadImage(src) { return new Promise((resolve, reject) => { let loadUrl = src; if (src.startsWith('http://') || src.startsWith('https://')) { loadUrl = 'https://images.weserv.nl/?url=' + encodeURIComponent(src) + '&output=jpg&q=95'; } const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => resolve(img); img.onerror = () => { const fallbackImg = new Image(); fallbackImg.crossOrigin = 'anonymous'; fallbackImg.onload = () => resolve(fallbackImg); fallbackImg.onerror = () => reject(new Error('Could not load image')); fallbackImg.src = src; }; img.src = loadUrl; }); } // --- 3D Canvas Multi-Theme Rendering Engine --- async function render3DCommercialPoster(canvas, productImg, title, price, badgeText, theme = 'obsidian_gold', aspect = '1:1', brand = 'glamourstouch') { const ctx = canvas.getContext('2d'); const w = canvas.width; const h = canvas.height; // Brand Header Profiles const BRAND_PROFILES = { glamourstouch: { headerTitle: "✨ GLAMOUR'S TOUCH ✨", headerSub: '100% AUTHENTIC KOREAN COSMETICS â€ĸ DERMATOLOGIST TESTED', badgeL1: 'đŸŒŋ Pure & Safe Care', badgeL2: 'đŸ›Ąī¸ Authentic Seal', footerSite: 'glamourstouch.com', footerHotline: '01712-426871' }, snehalata: { headerTitle: '🌸 SNEHALATA AURA 🌸', headerSub: 'PREMIUM LUXURY FASHION, SAREE & LIFESTYLE â€ĸ 100% AUTHENTIC', badgeL1: '👗 Pure Fabric Weave', badgeL2: '✨ Size Trial Guarantee', footerSite: 'snehalata.com', footerHotline: '01712-426871' }, techvolt: { headerTitle: '⚡ TECHVOLT GADGETS ⚡', headerSub: 'OFFICIAL WARRANTY â€ĸ SMART ELECTRONICS & AUDIO ACCESSORIES', badgeL1: '🔋 High Battery Life', badgeL2: 'đŸ›Ąī¸ 1 Year Warranty', footerSite: 'techvolt.auraajenticai.cloud', footerHotline: '01712-426871' }, organic: { headerTitle: 'đŸ¯ PRANON ORGANIC đŸ¯', headerSub: '100% PURE NATURAL HONEY & UNADULTERATED ORGANIC FOODS', badgeL1: 'đŸŒŋ 100% Lab Tested', badgeL2: 'đŸ›Ąī¸ Double Money Back', footerSite: 'organic.auraajenticai.cloud', footerHotline: '01712-426871' }, sneakerlab: { headerTitle: '👟 SNEAKERLAB BD 👟', headerSub: 'PREMIUM STREETWEAR & GENUINE LEATHER FOOTWEAR', badgeL1: '👟 Memory Foam Cushion', badgeL2: '✨ Doorstep Fitting', footerSite: 'sneakers.auraajenticai.cloud', footerHotline: '01712-426871' }, royale: { headerTitle: '💎 AURA ROYALE 💎', headerSub: 'LUXURY JEWELRY, WATCHES & 24-HOUR SIGNATURE PERFUMES', badgeL1: '💎 24h Projection', badgeL2: '👑 Pure Luxury Finish', footerSite: 'royale.auraajenticai.cloud', footerHotline: '01712-426871' }, custom: { headerTitle: 'đŸ›ī¸ PREMIUM E-COMMERCE đŸ›ī¸', headerSub: '100% ORIGINAL AUTHENTIC â€ĸ CASH ON DELIVERY BANGLADESH', badgeL1: '⭐ Premium Quality', badgeL2: 'đŸ›Ąī¸ 100% Original', footerSite: 'auraajenticai.cloud', footerHotline: '01712-426871' } }; const brandInfo = BRAND_PROFILES[brand] || BRAND_PROFILES.glamourstouch; // Theme palettes const THEMES = { obsidian_gold: { bgCenter: '#18212D', bgMid: '#0C1117', bgOuter: '#05080C', spotlightColor: '#FFFFFF', goldRim: '#E5B83A', ringColor: '#66E5B83A', pedestalTop: '#FFFFFF', pedestalMid: '#EBF2F8', pedestalDark: '#1B2533' }, rose_quartz: { bgCenter: '#2D1824', bgMid: '#170C13', bgOuter: '#0C0509', spotlightColor: '#FFF0F5', goldRim: '#F472B6', ringColor: '#F472B666', pedestalTop: '#FFF5F8', pedestalMid: '#FCE7F3', pedestalDark: '#371829' }, cyber_neon: { bgCenter: '#0F172A', bgMid: '#060E1A', bgOuter: '#02060D', spotlightColor: '#E0F2FE', goldRim: '#06B6D4', ringColor: '#06B6D466', pedestalTop: '#F0FDF4', pedestalMid: '#CFFAFE', pedestalDark: '#082F49' }, botanical_eco: { bgCenter: '#14281E', bgMid: '#0B1711', bgOuter: '#040B07', spotlightColor: '#F0FDF4', goldRim: '#10B981', ringColor: '#10B98166', pedestalTop: '#F7FEE7', pedestalMid: '#DCFCE7', pedestalDark: '#064E3B' } }; const currentTheme = THEMES[theme] || THEMES.obsidian_gold; // 1. Background Radial Gradient const stageCy = aspect === '9:16' ? h * 0.46 : h * 0.44; const bgGrad = ctx.createRadialGradient(w / 2, stageCy, 50, w / 2, stageCy, w * 0.75); bgGrad.addColorStop(0, currentTheme.bgCenter); bgGrad.addColorStop(0.6, currentTheme.bgMid); bgGrad.addColorStop(1, currentTheme.bgOuter); ctx.fillStyle = bgGrad; ctx.fillRect(0, 0, w, h); // 2. Spotlight const stageCx = w / 2; const stageRadius = w * 0.38; const spotGrad = ctx.createRadialGradient(stageCx, stageCy, 0, stageCx, stageCy, stageRadius); spotGrad.addColorStop(0, '#FFFFFF'); spotGrad.addColorStop(0.48, '#FFFFFF'); spotGrad.addColorStop(0.68, currentTheme.spotlightColor); spotGrad.addColorStop(0.85, '#64748B'); spotGrad.addColorStop(1, 'transparent'); ctx.fillStyle = spotGrad; ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius, 0, Math.PI * 2); ctx.fill(); // Glow Rings ctx.strokeStyle = currentTheme.ringColor; ctx.lineWidth = 2.5; ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius * 0.96, 0, Math.PI * 2); ctx.stroke(); ctx.setLineDash([12, 12]); ctx.beginPath(); ctx.arc(stageCx, stageCy, stageRadius * 0.91, 0, Math.PI * 2); ctx.stroke(); ctx.setLineDash([]); // 3. 3D Dual-Tier Podium const baseTierY = aspect === '9:16' ? 1220 : 745; const baseTierRx = w * 0.38; const baseTierRy = 34; const baseTierHeight = 26; // Base Shadow const baseShadow = ctx.createRadialGradient(stageCx, baseTierY + baseTierHeight + 16, 20, stageCx, baseTierY + baseTierHeight + 16, baseTierRx * 1.15); baseShadow.addColorStop(0, 'rgba(0,0,0,0.7)'); baseShadow.addColorStop(1, 'transparent'); ctx.fillStyle = baseShadow; drawOval(ctx, stageCx, baseTierY + baseTierHeight + baseTierRy * 0.6, baseTierRx * 1.15, baseTierRy * 1.6); // Base Cylinder Body const baseCylGrad = ctx.createLinearGradient(stageCx - baseTierRx, 0, stageCx + baseTierRx, 0); baseCylGrad.addColorStop(0, '#090D12'); baseCylGrad.addColorStop(0.5, '#475569'); baseCylGrad.addColorStop(1, '#090D12'); ctx.fillStyle = baseCylGrad; ctx.fillRect(stageCx - baseTierRx, baseTierY, baseTierRx * 2, baseTierHeight); drawOval(ctx, stageCx, baseTierY + baseTierHeight, baseTierRx, baseTierRy); drawOval(ctx, stageCx, baseTierY, baseTierRx, baseTierRy); // Top Tier const topTierY = aspect === '9:16' ? 1180 : 708; const topTierRx = w * 0.31; const topTierRy = 28; const topTierHeight = 34; const topCylGrad = ctx.createLinearGradient(stageCx - topTierRx, 0, stageCx + topTierRx, 0); topCylGrad.addColorStop(0, '#070A0E'); topCylGrad.addColorStop(0.5, currentTheme.goldRim); topCylGrad.addColorStop(1, '#070A0E'); ctx.fillStyle = topCylGrad; ctx.fillRect(stageCx - topTierRx, topTierY, topTierRx * 2, topTierHeight); drawOval(ctx, stageCx, topTierY + topTierHeight, topTierRx, topTierRy); // Top Surface Cap const topSurfaceGrad = ctx.createRadialGradient(stageCx, topTierY, 0, stageCx, topTierY, topTierRx); topSurfaceGrad.addColorStop(0, currentTheme.pedestalTop); topSurfaceGrad.addColorStop(0.5, currentTheme.pedestalMid); topSurfaceGrad.addColorStop(1, currentTheme.pedestalDark); ctx.fillStyle = topSurfaceGrad; drawOval(ctx, stageCx, topTierY, topTierRx, topTierRy); // Gold Beveled Rim ctx.strokeStyle = currentTheme.goldRim; ctx.lineWidth = 3.5; strokeOval(ctx, stageCx, topTierY, topTierRx, topTierRy); // 4. Product Scaling & Placement const targetH = aspect === '9:16' ? 560 : 500; const targetW = aspect === '9:16' ? 580 : 520; const srcW = productImg.width || 500; const srcH = productImg.height || 500; const scale = Math.min(targetW / srcW, targetH / srcH); const destW = srcW * scale; const destH = srcH * scale; const destLeft = (w - destW) / 2; const destTop = topTierY - destH + 18; // Floor Reflection (Multiply blend) ctx.save(); ctx.globalCompositeOperation = 'multiply'; ctx.globalAlpha = 0.25; ctx.translate(0, (topTierY + 6) * 2); ctx.scale(1, -1); ctx.drawImage(productImg, destLeft, topTierY + 6, destW, destH * 0.35); ctx.restore(); // Contact Drop Shadow const contactShadow = ctx.createRadialGradient(stageCx, topTierY, 10, stageCx, topTierY, destW * 0.4); contactShadow.addColorStop(0, 'rgba(0,0,0,0.8)'); contactShadow.addColorStop(1, 'transparent'); ctx.fillStyle = contactShadow; drawOval(ctx, stageCx, topTierY + 2, destW * 0.38, 12); // Product Image (Multiply blended to wipe white background) ctx.save(); ctx.globalCompositeOperation = 'multiply'; ctx.drawImage(productImg, destLeft, destTop, destW, destH); ctx.restore(); // 5. Value Trust Badges const badgeY1 = aspect === '9:16' ? 340 : 240; const badgeY2 = badgeY1 + 75; drawPillBadge(ctx, 40, badgeY1, badgeText, true, currentTheme.goldRim); drawPillBadge(ctx, 40, badgeY2, brandInfo.badgeL1, true, currentTheme.goldRim); drawPillBadge(ctx, w - 40, badgeY1, '⚡ Fast Delivery BD', false, currentTheme.goldRim); drawPillBadge(ctx, w - 40, badgeY2, brandInfo.badgeL2, false, currentTheme.goldRim); // 6. Header Ribbon ctx.fillStyle = '#F2090D12'; ctx.fillRect(0, 0, w, 92); ctx.strokeStyle = currentTheme.goldRim; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(0, 92); ctx.lineTo(w, 92); ctx.stroke(); ctx.fillStyle = currentTheme.goldRim; ctx.font = 'bold 32px Plus Jakarta Sans, sans-serif'; ctx.textAlign = 'center'; ctx.fillText(brandInfo.headerTitle, w / 2, 52); ctx.fillStyle = '#FFF4D0'; ctx.font = '16px Plus Jakarta Sans, sans-serif'; ctx.fillText(brandInfo.headerSub, w / 2, 80); // 7. Product Title Card const cleanTitle = title.length > 60 ? title.substring(0, 58) + '...' : title; const titleCardTop = h - (aspect === '9:16' ? 320 : 235); const titleCardBottom = h - (aspect === '9:16' ? 150 : 128); ctx.fillStyle = '#EA0B0E14'; roundRect(ctx, 28, titleCardTop, w - 56, titleCardBottom - titleCardTop, 18); ctx.fill(); ctx.strokeStyle = currentTheme.goldRim + '88'; ctx.lineWidth = 2; roundRect(ctx, 28, titleCardTop, w - 56, titleCardBottom - titleCardTop, 18); ctx.stroke(); ctx.fillStyle = '#FFFFFF'; ctx.font = 'bold 27px Plus Jakarta Sans, Hind Siliguri, sans-serif'; ctx.textAlign = 'center'; ctx.fillText(cleanTitle, w / 2, titleCardTop + 42); ctx.fillStyle = currentTheme.goldRim; ctx.font = 'bold 21px Hind Siliguri, sans-serif'; ctx.fillText(`${price} â€ĸ ā§§ā§Ļā§Ļ% āφāϏāϞ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ â€ĸ āĻĻā§āϰ⧁āϤ āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ`, w / 2, titleCardTop + 80); // 8. Bottom WhatsApp Banner const footerHeight = aspect === '9:16' ? 140 : 118; const footerTop = h - footerHeight; const footerGrad = ctx.createLinearGradient(0, footerTop, w, h); footerGrad.addColorStop(0, '#25D366'); footerGrad.addColorStop(1, '#1EB855'); ctx.fillStyle = footerGrad; ctx.fillRect(0, footerTop, w, footerHeight); ctx.fillStyle = '#FFFFFF'; ctx.font = 'bold 32px Plus Jakarta Sans, sans-serif'; ctx.textAlign = 'left'; ctx.fillText(`đŸ’Ŧ WhatsApp Order: ${brandInfo.footerHotline}`, 35, footerTop + 48); ctx.fillStyle = '#053314'; ctx.font = 'bold 20px Plus Jakarta Sans, sans-serif'; ctx.fillText(`🌐 Website: ${brandInfo.footerSite} â€ĸ 📞 Hotline: ${brandInfo.footerHotline}`, 35, footerTop + 90); // QR Code await drawWhatsAppQrOnCanvas(ctx, w - 130, footerTop + 11, 96); // Outer Border ctx.strokeStyle = currentTheme.goldRim + '99'; ctx.lineWidth = 6; ctx.strokeRect(3, 3, w - 6, h - 6); } function drawOval(ctx, cx, cy, rx, ry) { ctx.beginPath(); ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2); ctx.fill(); } function strokeOval(ctx, cx, cy, rx, ry) { ctx.beginPath(); ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2); ctx.stroke(); } function roundRect(ctx, x, y, width, height, radius) { ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.lineTo(x + width - radius, y); ctx.quadraticCurveTo(x + width, y, x + width, y + radius); ctx.lineTo(x + width, y + height - radius); ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); ctx.lineTo(x + radius, y + height); ctx.quadraticCurveTo(x, y + height, x, y + height - radius); ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); } function drawPillBadge(ctx, x, y, text, isLeft, goldColor = '#E5B83A') { ctx.font = 'bold 18px Plus Jakarta Sans, Hind Siliguri, sans-serif'; const textWidth = ctx.measureText(text).width; const pillW = textWidth + 28; const pillH = 36; const pillX = isLeft ? x : x - pillW; const pillY = y - 22; ctx.fillStyle = '#D90E141B'; roundRect(ctx, pillX, pillY, pillW, pillH, 18); ctx.fill(); ctx.strokeStyle = goldColor + '66'; ctx.lineWidth = 1.5; roundRect(ctx, pillX, pillY, pillW, pillH, 18); ctx.stroke(); ctx.fillStyle = '#FFF0C8'; ctx.textAlign = 'left'; ctx.fillText(text, pillX + 14, pillY + 24); } async function drawWhatsAppQrOnCanvas(ctx, x, y, size) { ctx.fillStyle = '#FFFFFF'; roundRect(ctx, x - 4, y - 4, size + 8, size + 8, 10); ctx.fill(); const qrContainer = document.getElementById('qrcodeHidden'); if (qrContainer) { qrContainer.innerHTML = ''; new QRCode(qrContainer, { text: 'https://wa.me/8801712426871', width: size, height: size, colorDark: '#0B2E13', colorLight: '#FFFFFF', correctLevel: QRCode.CorrectLevel.M }); await new Promise(r => setTimeout(r, 80)); const qrImg = qrContainer.querySelector('img') || qrContainer.querySelector('canvas'); if (qrImg) { ctx.drawImage(qrImg, x, y, size, size); } } } // --- Customer Care & Inbox AI Dedicated Studio --- function initInboxAI() { const customerMsgInput = document.getElementById('inboxCustomerMsg'); const storeContextInput = document.getElementById('inboxStoreContext'); const generateBtn = document.getElementById('generateInboxReplyBtn'); const statusMsg = document.getElementById('inboxStatusMsg'); const repliesCard = document.getElementById('inboxRepliesCard'); const reply1 = document.getElementById('replyText1'); const reply2 = document.getElementById('replyText2'); const reply3 = document.getElementById('replyText3'); if (!generateBtn) return; generateBtn.addEventListener('click', async () => { const query = customerMsgInput.value.trim(); const storeInfo = storeContextInput.value.trim(); const apiKey = localStorage.getItem('opal_gemini_api_key') || ''; const model = localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; if (!query) { alert('Please enter a customer message'); return; } statusMsg.classList.remove('hidden'); statusMsg.textContent = 'âŗ Generating 3 sweet & polite sales replies with Gemini AI...'; generateBtn.disabled = true; try { if (apiKey) { const prompt = `A customer sent this message in e-commerce inbox: '${query}' Store Info: ${storeInfo} Write 3 ready-to-copy customer responses in natural, sweet BENGALI (āĻŦāĻžāĻ‚āϞāĻž). Format exactly with: ---REPLY1--- (Instant polite greeting and direct answer with price & benefits) ---REPLY2--- (Order confirmation closer asking for Name, Address, and Phone number) ---REPLY3--- (1-click WhatsApp order link: https://wa.me/8801712426871 and hotline 01712-426871)`; const result = await callGeminiApi(apiKey, model, prompt); const parts = result.split(/---REPLY[123]---/); reply1.textContent = (parts[1] || 'āφāϏāϏāĻžāϞāĻžāĻŽā§ āφāϞāĻžāχāϕ⧁āĻŽ āĻĒā§āϰāĻŋ⧟ āĻ•āĻžāĻ¸ā§āϟāĻŽāĻžāϰ! āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāĻĄāĻžāĻ•ā§āĻŸā§‡āϰ āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ āĻŽāĻžāĻ¤ā§āϰ ā§ŗā§§ā§Ļā§Ŧā§ĻāĨ¤ āĻāϟāĻŋ ā§§ā§Ļā§Ļ% āφāϏāϞ āĻĒā§āϰāĻĄāĻžāĻ•ā§āϟāĨ¤').trim(); reply2.textContent = (parts[2] || 'āĻ…āĻ°ā§āĻĄāĻžāϰāϟāĻŋ āĻ•āύāĻĢāĻžāĻ°ā§āĻŽ āĻ•āϰāϤ⧇ āφāĻĒāύāĻžāϰ āύāĻžāĻŽ, āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ āĻŋāĻ•āĻžāύāĻž āĻāĻŦāĻ‚ āĻŽā§‹āĻŦāĻžāχāϞ āύāĻŽā§āĻŦāϰāϟāĻŋ āϞāĻŋāϖ⧇ āĻĒāĻžāĻ āĻžāύāĨ¤ āφāĻŽāϰāĻž āĻĻā§āϰ⧁āϤ āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻ⧇āĻŦā§‹!').trim(); reply3.textContent = (parts[3] || 'āϏāϰāĻžāϏāϰāĻŋ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇ āĻĻā§āϰ⧁āϤ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ: https://wa.me/8801712426871\nāĻšāϟāϞāĻžāχāύ: 01712-426871').trim(); } else { reply1.textContent = `āφāϏāϏāĻžāϞāĻžāĻŽā§ āφāϞāĻžāχāϕ⧁āĻŽ āĻĒā§āϰāĻŋ⧟ āφāĻĒ⧁/āĻ­āĻžāĻ‡ā§ŸāĻž! đŸĨ°\nāφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϕ⧋āϰāĻŋ⧟āĻžāύ āĻ¸ā§āĻ•āĻŋāύāĻ•ā§‡ā§ŸāĻžāϰ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤\n\n💰 āĻ…āĻĢāĻžāϰ āĻŽā§‚āĻ˛ā§āϝ: ā§ŗ ā§§,ā§Ļā§Ŧā§Ļ (āϰ⧇āϗ⧁āϞāĻžāϰ ā§ŗ ā§§,ā§Ēā§­ā§Ļ)\n🚚 āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ: āĻĸāĻžāĻ•āĻžā§Ÿ ā§ŗā§­ā§Ļ, āĻĸāĻžāĻ•āĻžāϰ āĻŦāĻžāχāϰ⧇ ā§ŗā§§ā§Šā§Ļ\n\nāĻāϟāĻŋ āύāĻŋ⧟āĻŽāĻŋāϤ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇ āĻ¤ā§āĻŦāĻ• āĻšāĻŦ⧇ āĻ•āĻžāĻšā§‡āϰ āĻŽāϤ⧋ āϚāĻ•āϚāϕ⧇ āĻ“ āĻĻāĻžāĻ—āĻšā§€āύ! 🌸`; reply2.textContent = `āĻ…āĻ°ā§āĻĄāĻžāϰāϟāĻŋ āĻ•āύāĻĢāĻžāĻ°ā§āĻŽ āĻ•āϰāϤ⧇ āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āφāĻĒāύāĻžāϰ:\nā§§. āύāĻžāĻŽ\n⧍. āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ āĻŋāĻ•āĻžāύāĻž (āĻœā§‡āϞāĻž/āĻĨāĻžāύāĻž āϏāĻš)\nā§Š. āĻŽā§‹āĻŦāĻžāχāϞ āύāĻŽā§āĻŦāϰ\n\nāϞāĻŋāϖ⧇ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻāĻŋāύāĨ¤ āφāĻŽāϰāĻž āĻĻā§āϰ⧁āϤ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻ⧇āĻŦā§‹! āϧāĻ¨ā§āϝāĻŦāĻžāĻĻāĨ¤ đŸ›ī¸`; reply3.textContent = `āϏāϰāĻžāϏāϰāĻŋ āĻšā§‹ā§ŸāĻžāϟāϏāĻ…ā§āϝāĻžāĻĒ⧇ ā§§-āĻ•ā§āϞāĻŋāϕ⧇ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ:\nđŸ’Ŧ WhatsApp: https://wa.me/8801712426871\n📞 āĻšāϟāϞāĻžāχāύ: 01712-426871\n🌐 āĻ“ā§Ÿā§‡āĻŦāϏāĻžāχāϟ: https://glamourstouch.com`; } repliesCard.classList.remove('hidden'); statusMsg.classList.add('hidden'); repliesCard.scrollIntoView({ behavior: 'smooth' }); } catch (e) { statusMsg.textContent = `❌ Error: ${e.message}`; } generateBtn.disabled = false; }); } // --- History Management --- function initHistory() { const historyContainer = document.getElementById('historyListContainer'); const clearBtn = document.getElementById('clearHistoryBtn'); function renderHistory() { if (!historyContainer) return; const list = JSON.parse(localStorage.getItem('opal_history') || '[]'); if (list.length === 0) { historyContainer.innerHTML = `
📭

No generations yet. Create your first 3D poster or mini-app generation!

`; return; } historyContainer.innerHTML = list.map(item => `
${item.type === '3D Poster' ? '🎨' : '⚡'}
${item.type}

${item.title}

${item.price || item.type}

`).join(''); } if (clearBtn) { clearBtn.addEventListener('click', () => { localStorage.removeItem('opal_history'); renderHistory(); }); } renderHistory(); } function saveGenerationToHistory(item) { const list = JSON.parse(localStorage.getItem('opal_history') || '[]'); list.unshift(item); localStorage.setItem('opal_history', JSON.stringify(list.slice(0, 30))); } // --- 7. Google Flow & Omni UGC Video Ads Studio (Google Veo 3.1) --- let selectedUgcPreset = 'unhinged_review'; const UGC_PRESET_LIBRARY = { unhinged_review: { name: 'Raw iPhone Unfiltered Review', styleDescription: 'Front-camera 4K selfie video, natural room lighting, casual clothing, real Bengali conversational talking-head with authentic micro-expressions and unboxing texture close-up.', cameraSettings: 'iPhone 15 Pro Max Front Camera 4K 60fps, subtle handheld organic wobble, autofocus hunting onto product label at 0:08, natural eye contact, warm ambient room light.', timelineTemplate: [ { time: '0:00 - 0:03', title: 'đŸ’Ĩ Disruptive Curiosity Hook', visual: 'Creator holds phone with one hand, looking shocked/excited directly at the lens. Holds {{product}} close to camera.', script: '"āϏāĻŦāĻžāχ āϝ⧇ āĻāχ {{product}} āύāĻŋā§Ÿā§‡ āĻāϤ āĻ•āĻĨāĻž āĻŦāϞāĻ›ā§‡â€”āϏāĻ¤ā§āϝāĻŋ āĻŦāϞāϤ⧇ āχāωāϜ āĻ•āϰāĻžāϰ āĻĒāϰ āφāĻŽāĻŋ āϜāĻžāĻ¸ā§āϟ āĻ…āĻŦāĻžāĻ• āĻšā§Ÿā§‡ āϗ⧇āĻ›āĻŋ!"' }, { time: '0:03 - 0:07', title: '😩 Problem & Relatable Agitation', visual: 'Creator shows daily struggle or low quality alternative, shaking head.', script: '"āĻŽāĻžāĻ°ā§āϕ⧇āĻŸā§‡ āĻ•āĻŽāĻĻāĻžāĻŽāĻŋ āĻĢ⧇āĻ• āϜāĻŋāύāĻŋāϏ⧇ āϟāĻžāĻ•āĻž āύāĻˇā§āϟ āĻ•āϰāĻžāϰ āĻšā§‡ā§Ÿā§‡ āφāϏāϞ āϜāĻŋāύāĻŋāϏ āύ⧇āĻ“ā§ŸāĻž āĻ•āϤ āϜāϰ⧁āϰāĻŋ, āϏ⧇āϟāĻž āĻāĻ–āύ āĻŦ⧁āĻāϤ⧇ āĻĒāĻžāϰāĻ›āĻŋ!"' }, { time: '0:07 - 0:12', title: '✨ Product Demo & Feature Macro', visual: 'Macro close-up: Creator demonstrates {{product}}, shows premium finish and instant performance.', script: '"āϜāĻžāĻ¸ā§āϟ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āφāϰ āĻĢāĻŋāύāĻŋāĻļāĻŋāĻ‚āϟāĻž āĻĻ⧇āϖ⧇āĻ¨â€”ā§§ā§Ļā§Ļ% āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āφāϰ āφāϏāϞ āĻšāĻ“ā§ŸāĻžāϰ āĻĢāĻŋāϞāϟāĻžāχ āφāϞāĻžāĻĻāĻž!"' }, { time: '0:12 - 0:15', title: '🛒 Social Proof & Urgency CTA', visual: 'Creator smiles radiantly, points to screen link with cash on delivery sticker.', script: '"ā§§ā§Ļā§Ļ% āφāϏāϞ āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āĻĒ⧇āϤ⧇ āĻāĻ–āύāχ āύāĻŋāĻšā§‡āϰ āϞāĻŋāĻ‚āϕ⧇ āĻŽā§‡āϏ⧇āϜ āĻĻāĻŋāύ!"' } ] }, fashion_tryon: { name: 'Fashion OOTD & Saree/Panjabi Drape', styleDescription: 'Aesthetic full-body bedroom & natural daylight mirror try-on, slow-motion fabric flow, close-up texture weave, high elegance Bangladeshi fashion presentation.', cameraSettings: '9:16 vertical 4K 60fps, 50mm portrait lens, f/1.8 shallow depth, gentle panning shot down the length of fabric, natural afternoon window light.', timelineTemplate: [ { time: '0:00 - 0:03', title: '👗 OOTD Fashion Hook', visual: 'Creator steps back from mirror, doing a graceful 360-degree spin showing the gorgeous fit of {{product}}.', script: '"āĻĻāĻžāĻ“ā§ŸāĻžāϤ āĻŦāĻž āĻ¸ā§āĻĒ⧇āĻļāĻžāϞ āĻ…āϕ⧇āĻļāύ⧇ āĻāχ āĻļāĻžā§œāĻŋ/āĻĄā§āϰ⧇āϏāϟāĻž āĻĒāϰ⧇ āϗ⧇āϞ⧇ āϏāĻŦāĻžāϰ āĻšā§‹āĻ– āφāĻĒāύāĻžāϰ āĻĻāĻŋāϕ⧇āχ āĻĨāĻžāĻ•āĻŦ⧇!"' }, { time: '0:03 - 0:07', title: 'đŸ§ĩ Fabric & Weave Macro Zoom', visual: 'Macro shot of hand gently gliding over the pure soft fabric, catching light reflections.', script: '"āĻ•āĻžāĻĒ⧜āϟāĻž āĻ•āϤāϟāĻž āϏāĻĢāϟ āφāϰ āφāϰāĻžāĻŽāĻĻāĻžā§ŸāĻ•, āϜāĻžāĻ¸ā§āϟ āĻĢāĻŋāύāĻŋāĻļāĻŋāĻ‚ āφāϰ āϏ⧁āϤāĻžāϰ āĻ•āĻžāϜāϟāĻž āĻĻ⧇āĻ–āϞ⧇āχ āĻŦ⧁āĻāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ!"' }, { time: '0:07 - 0:12', title: '✨ Styling & Fitting Silhouette', visual: 'Creator styling with matching accessories, smiling with confidence in natural daylight.', script: '"āĻļāϰ⧀āϰ⧇ āĻāĻ•āĻĻāĻŽ āĻĒāĻžāϰāĻĢ⧇āĻ•ā§āϟ āĻĢāĻŋāϟ āĻšā§Ÿā§‡ āĻĨāĻžāϕ⧇āĨ¤ āϕ⧋āύ⧋ āĻ…āĻ¸ā§āĻŦāĻ¸ā§āϤāĻŋ āĻ›āĻžā§œāĻžāχ āϏāĻžāϰāĻžāĻĻāĻŋāύ āĻĒāϰ⧇ āĻĨāĻžāĻ•āĻž āϝāĻžāĻŦ⧇!"' }, { time: '0:12 - 0:15', title: 'đŸ›ī¸ Size Choice & 1-Click Order', visual: 'Holding boutique packaging bag, pointing to WhatsApp order button.', script: '"āĻĒāĻ›āĻ¨ā§āĻĻ⧇āϰ āĻ•āĻžāϞāĻžāϰ āĻ“ āϏāĻžāχāϜ āĻŦ⧁āĻ• āĻ•āϰāϤ⧇ āĻāĻ–āύāχ āύāĻŋāĻšā§‡ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύāĨ¤ āĻĢā§āϰāĻŋ āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āϚāĻžāϞ⧁ āφāϛ⧇!"' } ] }, gadget_unboxing: { name: 'Smart Gadget Sound & Stress Test', styleDescription: 'Futuristic desk setup with RGB neon rim light, macro lens focusing on digital display, water-resistance spray test, tactile button press response.', cameraSettings: 'Top-down macro 4K, 120fps ultra slow-mo, cyberpunk teal & orange lighting, clean audio capturing crisp click sensations.', timelineTemplate: [ { time: '0:00 - 0:03', title: '⚡ Tech Power-On Hook', visual: 'Hands slicing open gadget box. Screen lights up with vibrant AMOLED colors showing {{product}}.', script: '"āĻāχ āĻŦāĻžāĻœā§‡āĻŸā§‡ āĻāϤ āĻĒāĻžāĻ“ā§ŸāĻžāϰāĻĢ⧁āϞ āĻĢāĻŋāϚāĻžāϰāϏ āφāϰ āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻŦāĻŋāĻ˛ā§āĻĄ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ—āĻŦāĻŋāĻļā§āĻŦāĻžāϏāχ āĻšāĻšā§āĻ›āĻŋāϞ āύāĻž!"' }, { time: '0:03 - 0:07', title: '💧 Extreme Water & Drop Test', visual: 'Spraying water mist on the gadget screen while active; wiping off cleanly without any glitch.', script: '"IP68 āĻ“ā§ŸāĻžāϟāĻžāϰāĻĒā§āϰ⧁āĻĢ āφāϰ āĻŽā§‡āϟāĻžāϞ āĻŦāĻĄāĻŋ āĻĢā§āϰ⧇āĻŽāĨ¤ āĻŦ⧃āĻˇā§āϟāĻŋ āĻŦāĻž āϰāĻžāĻĢ āχāωāĻœâ€”āϝ⧇āϕ⧋āύ⧋ āĻ•āĻ¨ā§āĻĄāĻŋāĻļāύ⧇ āĻāĻ•āĻĻāĻŽ āϰāĻ• āϏāϞāĻŋāĻĄ!"' }, { time: '0:07 - 0:12', title: '🔋 Battery & ANC Audio Demo', visual: 'Finger tapping touch controls, smooth 60Hz UI scrolling and seamless Bluetooth connection.', script: '"āĻāĻ• āϚāĻžāĻ°ā§āĻœā§‡ āϟāĻžāύāĻž ā§­ āĻĻāĻŋāύ⧇āϰ āĻŦā§āϝāĻžāϟāĻžāϰāĻŋ āĻŦā§āϝāĻžāĻ•āφāĻĒ āφāϰ āĻŦ⧇āϜ āϏāĻžāωāĻ¨ā§āĻĄ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āĻāĻ•āĻĻāĻŽ āύ⧇āĻ•ā§āϏāϟ āϞ⧇āϭ⧇āϞ!"' }, { time: '0:12 - 0:15', title: 'đŸ›Ąī¸ Official Warranty & COD CTA', visual: 'Displaying official 1-year replacement warranty card and fast dispatch flyer.', script: '"ā§§ āĻŦāĻ›āϰ⧇āϰ āĻ…āĻĢāĻŋāϏāĻŋ⧟āĻžāϞ āϰāĻŋāĻĒā§āϞ⧇āϏāĻŽā§‡āĻ¨ā§āϟ āĻ“ā§ŸāĻžāϰ⧇āĻ¨ā§āϟāĻŋ āϏāĻš āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āύāĻŋāϤ⧇ āĻāĻ–āύāχ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰ⧁āύ!"' } ] }, sneaker_flex: { name: 'Sneaker Flex & Kick Test', styleDescription: 'Street style sneakerhead perspective, dynamic footwork on pavement, slow-mo sole flexion, crisp leather crease resistance check.', cameraSettings: 'Low-angle ground tracking shot, 4K 60fps, dynamic gimbal push-in, natural street sun flare.', timelineTemplate: [ { time: '0:00 - 0:03', title: '👟 Street Flex Entry', visual: 'Low angle shot of creator stepping into frame wearing {{product}}, doing a quick heel-toe flex.', script: '"āĻ¸ā§āύāĻŋāĻ•āĻžāϰ āϞāĻžāĻ­āĻžāϰāĻĻ⧇āϰ āϜāĻ¨ā§āϝ āĻāχ āĻĒ⧇āϝāĻŧāĻžāϰāϟāĻž āϜāĻžāĻ¸ā§āϟ āφāϗ⧁āύ! āϞ⧁āĻ• āφāϰ āĻ•āĻŽāĻĢā§‹āĻ°ā§āϟ āĻĻ⧁āĻŸā§‹āχ āϟāĻĒ āύāϚ!"' }, { time: '0:03 - 0:07', title: 'đŸ›Ąī¸ Sole Cushion & Crease Test', visual: 'Bending the sole with hands showing memory foam bounce back, no deep creases.', script: '"āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻĢā§‹āĻŽ āχāύāϏ⧋āϞ āĻšāĻ“ā§ŸāĻžā§Ÿ āϏāĻžāϰāĻžāĻĻāĻŋāύ āĻšā§‡āρāĻŸā§‡āĻ“ āĻĒāĻžā§Ÿā§‡ āϕ⧋āύ⧋ āĻŦā§āϝāĻĨāĻž āĻšāĻŦ⧇ āύāĻžāĨ¤ āϞ⧇āĻĻāĻžāϰ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ ā§§ā§Ļā§Ļ% āĻĒāĻŋāĻ“āϰ!"' }, { time: '0:07 - 0:12', title: 'đŸ”Ĩ Outfit Pairing Display', visual: 'Wide street shot pairing the sneakers with denim & cargo streetwear.', script: '"āϜāĻŋāĻ¨ā§āϏ āĻ•āĻŋāĻ‚āĻŦāĻž āĻ•āĻžāĻ°ā§āĻ—ā§‹â€”āϝ⧇āϕ⧋āύ⧋ āĻ•ā§āϝāĻžāϜ⧁⧟āĻžāϞ āφāωāϟāĻĢāĻŋāĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āϞ⧁āĻ•āϟāĻž āĻāĻ•āĻĻāĻŽ āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻĢ⧁āĻŸā§‡ āωāĻ āĻŦ⧇!"' }, { time: '0:12 - 0:15', title: 'đŸ“Ļ Doorstep Size Trial CTA', visual: 'Holding genuine sneaker box with size chart guarantee on screen.', script: '"āĻšā§‹āĻŽ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āϏāĻžāχāϜ āĻŸā§āϰāĻžā§ŸāĻžāϞ āϏ⧁āĻŦāĻŋāϧāĻž āϏāĻš āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āĻŦ⧁āĻ• āĻ•āϰāϤ⧇ āĻāĻ–āύāχ āĻŽā§‡āϏ⧇āϜ āĻĻāĻŋāύ!"' } ] }, organic_purity: { name: 'Organic Honey & Food Purity Test', styleDescription: 'Sunlit rustic wooden kitchen table, glass jar of pure golden honey, wooden honey dipper slow swirl, water glass drop dissolving test.', cameraSettings: 'Macro 4K f/2.8, warm sunlit golden flare, extreme slow-mo 120fps honey dripping into water without clouding.', timelineTemplate: [ { time: '0:00 - 0:03', title: 'đŸ¯ Pure Nature Swirl Hook', visual: 'Wooden dipper lifting thick golden {{product}}, thick continuous thread without breaking.', script: '"āĻ–āĻžāρāϟāĻŋ āĻŽāϧ⧁āϰ āφāϏāϞ āĻšā§‡āύāĻžāϰ āωāĻĒāĻžā§Ÿ āĻ•āĻŋ āϜāĻžāύ⧇āύ? āĻāχ āĻĻ⧇āϖ⧁āĻ¨â€”āĻāĻ• āĻĢā§‹āρāϟāĻžāĻ“ āĻ›āĻŋāĻā§œā§‡ āĻĒ⧜āĻŦ⧇ āύāĻž!"' }, { time: '0:03 - 0:07', title: 'đŸ§Ē Live Water Dissolve Test', visual: 'Dripping honey into clear glass of water; honey settles at bottom without mixing instantly.', script: '"āĻĒāĻžāύāĻŋāϰ āĻ—ā§āϞāĻžāϏ⧇ āĻĻ⧇āĻ“ā§ŸāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇āχ āύāĻŋāĻšā§‡ āĻ—āĻŋā§Ÿā§‡ āϜāĻŽāĻžāϟ āĻŦāĻžāρāϧāĻ˛â€”ā§§ā§Ļā§Ļ% āύāĻŋāĻ°ā§āϭ⧇āϜāĻžāϞ āĻ“ āĻ–āĻžāρāϟāĻŋ āĻĒā§āϰāĻžāĻ•ā§ƒāϤāĻŋāĻ• āĻŽāϧ⧁!"' }, { time: '0:07 - 0:12', title: 'đŸŒŋ Raw Aroma & Health Benefits', visual: 'Creator taking a small spoonful, expressing delight at the authentic floral aroma and taste.', script: '"āĻĒā§āϰāĻžāĻ•ā§ƒāϤāĻŋāĻ• āĻ¸ā§āĻŦāĻžāĻĻ āφāϰ āϏ⧁āĻŦāĻžāϏ⧇ āĻ­āϰāĻžāĨ¤ āĻĒāϰāĻŋāĻŦāĻžāϰ⧇āϰ āϰ⧋āĻ— āĻĒā§āϰāϤāĻŋāϰ⧋āϧ āĻ•ā§āώāĻŽāϤāĻž āĻŦāĻžā§œāĻžāϤ⧇ āĻĒā§āϰāϤāĻŋāĻĻāĻŋāύ āĻāĻ• āϚāĻžāĻŽāϚāχ āϝāĻĨ⧇āĻˇā§āϟāĨ¤"' }, { time: '0:12 - 0:15', title: 'đŸ›Ąī¸ 100% Purity Guarantee CTA', visual: 'Displaying lab test report and eco-friendly packing with cash-on-delivery guarantee.', script: '"āϭ⧇āϜāĻžāϞ āĻĒā§āϰāĻŽāĻžāĻŖāĻŋāϤ āĻšāϞ⧇ āĻĄāĻžāĻŦāϞ āĻŽāĻžāύāĻŋ-āĻŦā§āϝāĻžāĻ• āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ! āĻāĻ–āύāχ āφāϏāϞ āĻŽāϧ⧁ āϘāϰ⧇ āĻĒ⧇āϤ⧇ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύāĨ¤"' } ] }, perfume_reaction: { name: 'Luxury Perfume 24-Hour Projection', styleDescription: 'Luxury dark obsidian backdrop, golden mist atomizer spray caught in volumetric beam of light, public compliment reactions.', cameraSettings: 'High-speed 4K macro spray capture, anamorphic lens flare, moody golden rim lighting.', timelineTemplate: [ { time: '0:00 - 0:03', title: '💎 Atomizer Mist Hook', visual: 'Slow motion fine mist spray from golden luxury bottle of {{product}} against dark background.', script: '"āĻāχ āĻĒāĻžāϰāĻĢāĻŋāωāĻŽāϟāĻž āĻĻāĻŋā§Ÿā§‡ āĻŦāĻžāχāϰ⧇ āϗ⧇āϞ⧇ āĻŽāĻžāύ⧁āώ āϘ⧁āϰ⧇ āϤāĻžāĻ•āĻžāϤ⧇ āĻŦāĻžāĻ§ā§āϝ! āϏ⧁āĻŦāĻžāϏāϟāĻž āϜāĻžāĻ¸ā§āϟ āφāύāϰāĻŋā§Ÿā§‡āϞ!"' }, { time: '0:03 - 0:07', title: '🌸 Scent Notes & Projection', visual: 'Creator spraying on wrist and collarbone, describing top notes of vanilla, amber and oud.', script: '"āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ āĻĢā§āϰ⧇āĻžā§āϚ āĻ“ āĻ…ā§āϝāĻžāϰāĻžāĻŦāĻŋāĻ• āύ⧋āϟāϏ⧇āϰ āĻŦā§āϞ⧇āĻ¨ā§āĻĄāĨ¤ āĻāĻ•āĻŦāĻžāϰ āĻĻāĻŋāϞ⧇ āϜāĻžāĻŽāĻžā§Ÿ āϏ⧁āĻŦāĻžāϏ āĻĨāĻžāϕ⧇ ⧍ā§Ē āϘāĻŖā§āϟāĻžāϰāĻ“ āĻŦ⧇āĻļāĻŋ!"' }, { time: '0:07 - 0:12', title: '✨ Compliment Magnet Test', visual: 'Friends and colleagues walking past, smiling and asking what perfume it is.', script: '"āĻ…āĻĢāĻŋāϏ, āĻĒāĻžāĻ°ā§āϟāĻŋ āĻ•āĻŋāĻ‚āĻŦāĻž āĻĄā§‡āϟ āύāĻžāχāĻŸâ€”āϏāĻŦ āϜāĻžā§ŸāĻ—āĻžā§Ÿ āφāĻĒāύāĻžāϕ⧇ āĻĻ⧇āĻŦ⧇ āĻāĻ• āφāĻ•āĻ°ā§āώāĻŖā§€ā§Ÿ āφāĻ­āĻŋāϜāĻžāĻ¤ā§āϝāĨ¤"' }, { time: '0:12 - 0:15', title: '🛒 Luxury Decant / Full Bottle CTA', visual: 'Luxury box and tester kit shown with WhatsApp direct link.', script: '"ā§§ā§Ļā§Ļ% āϞāĻ‚ āϞāĻžāĻ¸ā§āϟāĻŋāĻ‚ āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϏ⧁āĻ—āĻ¨ā§āϧāĻŋ āĻĒ⧇āϤ⧇ āĻāĻ–āύāχ āύāĻŋāĻšā§‡ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻŦāĻžāϟāύ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ!"' } ] }, grwm_mirror: { name: 'Bathroom Mirror GRWM + Glass Skin', styleDescription: 'Aesthetic morning routine in a clean modern bathroom with golden morning sunlight hitting the mirror, soft focus background, organic skincare application.', cameraSettings: 'Cinematic 9:16 vertical, f/1.8 shallow depth of field, warm golden-hour side lighting, macro zoom onto water droplets and glowing skin absorption.', timelineTemplate: [ { time: '0:00 - 0:03', title: 'đŸĒž Morning GRWM Hook', visual: 'Morning sunshine reflecting on mirror. Creator wearing silk headband, looking at glowing skin.', script: '"Get Ready With Me! āφāϜāϕ⧇āϰ āĻĻāĻŋāύ⧇ āϝāĻžāĻĻ⧇āϰ āϏāĻžāϰāĻžāĻĻāĻŋāύ āĻ—ā§āϞāĻžāϏ āĻ¸ā§āĻ•āĻŋāύ āĻ—ā§āϞ⧋ āϧāϰ⧇ āϰāĻžāĻ–āϤ⧇ āĻšāĻŦ⧇, āϤāĻžāĻĻ⧇āϰ āϜāĻ¨ā§āϝ āφāĻŽāĻžāϰ āϏāĻŋāĻ•ā§āϰ⧇āϟ āϰ⧁āϟāĻŋāύ..."' }, { time: '0:03 - 0:07', title: '🌸 Step-by-Step Application', visual: 'Dipping finger/dropper into {{product}}, smooth glide across cheekbones and forehead.', script: '"āϘ⧁āĻŽ āĻĨ⧇āϕ⧇ āωāϠ⧇ āĻŽā§āĻ– āĻ§ā§ā§Ÿā§‡ āĻāχ {{product}} āϜāĻžāĻ¸ā§āϟ ⧍ āĻĢā§‹āρāϟāĻž āĻŽā§āϝāĻžāϏāĻžāϜ āĻ•āϰ⧇ āύāĻŋāχāĨ¤ āĻ¤ā§āĻŦāϕ⧇āϰ āĻ—āĻ­ā§€āϰ⧇ āĻ—āĻŋā§Ÿā§‡ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻšāĻžāχāĻĄā§āϰ⧇āĻļāύ āϞāĻ• āĻ•āϰ⧇!"' }, { time: '0:07 - 0:12', title: '💎 Real Light Absorption Test', visual: 'Creator turns face left and right in natural light—skin reflects a glossy, crystal-clear mirror shine.', script: '"āϕ⧋āύ⧋ āĻŽā§‡āĻ•āφāĻĒ āĻ›āĻžā§œāĻž āĻ¨ā§āϝāĻžāϚāĻžāϰāĻžāϞ āĻ¸ā§āĻ•āĻŋāύ⧇āχ āĻāχ āĻļāĻžāχāύāϟāĻž āĻĒāĻžāĻšā§āϛ⧇āύāĨ¤ āϏāĻžāϰāĻžāĻĻāĻŋāύ āĻŽā§āĻ– āĻāĻ•āĻĻāĻŽ āύāϰāĻŽ āφāϰ āĻĢā§āϰ⧇āĻļ āĻĨāĻžāϕ⧇!"' }, { time: '0:12 - 0:15', title: 'đŸ›ī¸ Special Offer & Order CTA', visual: 'Creator picks up bag, waves happily to camera, on-screen WhatsApp hotline pop-up.', script: '"āφāϜāχ āĻ¸ā§āĻĒ⧇āĻļāĻžāϞ āĻĄāĻŋāϏāĻ•āĻžāωāĻ¨ā§āĻŸā§‡ āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞāϟāĻž āύāĻŋāϤ⧇ glamourstouch.com āĻŦāĻž WhatsApp-āĻ āύāĻ• āĻĻāĻŋāύ!"' } ] }, unboxing_asmr: { name: 'POV First-Person Unboxing ASMR', styleDescription: 'POV first-person angle over a clean wooden marble desk. Hands opening official courier flyer, crisp peeling sound, glossy box reveal, tactile product feel.', cameraSettings: 'Top-down 45-degree angle, 4K macro lens, studio ring light + warm softbox, rich tactile audio/visual sensations.', timelineTemplate: [ { time: '0:00 - 0:03', title: 'đŸ“Ļ Satisfying Unboxing Hook', visual: 'POV hands slicing open courier parcel with satisfying tear. Bubble wrap peeled to reveal authentic {{product}}.', script: '[ASMR: Crispy package opening sound] "āĻ…āĻŦāĻļ⧇āώ⧇ āφāĻŽāĻžāϰ āĻŽā§‹āĻ¸ā§āϟ āĻ“ā§Ÿā§‡āχāĻŸā§‡āĻĄ āĻĒāĻžāĻ°ā§āϏ⧇āϞāϟāĻž āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋ āĻĒ⧇āϞāĻžāĻŽ!"' }, { time: '0:03 - 0:07', title: 'đŸ›Ąī¸ Authenticity Verification', visual: 'Hands turning the luxury box around, zooming in on authentic hologram seal and QR sticker.', script: '"ā§§ā§Ļā§Ļ% āĻ…āϰāĻŋāϜāĻŋāύāĻžāϞ āϏāĻŋāĻ•āĻŋāωāϰāĻŋāϟāĻŋ āϏāĻŋāϞ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰāĻž āφāϛ⧇āĨ¤ āĻĒā§āϝāĻžāϕ⧇āϜāĻŋāĻ‚āϟāĻžāχ āϤ⧋ āĻŽāĻžāĻĨāĻž āύāĻˇā§āϟ!"' }, { time: '0:07 - 0:12', title: 'đŸ§Ē Luxurious Swatch / Feel', visual: 'Unboxing product, showing clean tactile premium finish.', script: '"āϜāĻžāĻ¸ā§āϟ āĻĢāĻŋāϞāϟāĻž āĻĻ⧇āϖ⧇āĻ¨â€”āϕ⧀ āĻĒāϰāĻŋāĻŽāĻžāĻŖ āĻĒā§āϰāĻŋāĻŽāĻŋ⧟āĻžāĻŽ! āĻāĻ• āĻĻ⧇āĻ–āĻžāϤ⧇āχ āĻŽāύ āĻ­āϰ⧇ āϝāĻžā§ŸāĨ¤"' }, { time: '0:12 - 0:15', title: '⚡ Fast Delivery & COD CTA', visual: 'Parcel invoice and hotline sticker shown with WhatsApp order button.', script: '"āĻ•ā§āϝāĻžāĻļ āĻ…āύ āĻĄā§‡āϞāĻŋāĻ­āĻžāϰāĻŋāϤ⧇ āĻĻā§āϰ⧁āϤ āĻĒ⧇āϤ⧇ āĻāĻ–āύāχ āύāĻŋāĻšā§‡ āĻŽā§‡āϏ⧇āϜ āĻ•āϰ⧁āύ!"' } ] }, skeptic_test: { name: 'Viral Claim Skeptic Test', styleDescription: 'Investigative, high-retention TikTok testing format. Direct close-up testing performance before and after.', cameraSettings: 'Punchy fast zooms, dynamic screen text overlays, high-contrast clean lighting, high energy facial delivery.', timelineTemplate: [ { time: '0:00 - 0:03', title: 'âš ī¸ High-Stakes Skeptic Hook', visual: 'Creator holds {{product}}, looking skeptical at claim.', script: '"āϏāĻŦāĻžāχ āϝ⧇ {{product}} āύāĻŋā§Ÿā§‡ āϞāĻžāĻĢāĻžāϞāĻžāĻĢāĻŋ āĻ•āϰāĻ›ā§‡â€”āφāϏāϞ⧇āχ āĻ•āĻŋ āĻāϟāĻž āĻ•āĻžāϜ āĻ•āϰ⧇ āύāĻžāĻ•āĻŋ āĻļ⧁āϧ⧁āχ āĻšāĻžāχāĻĒ? āϚāϞ⧇āύ āϞāĻžāχāĻ­ āĻŸā§‡āĻ¸ā§āϟ āĻ•āϰāĻŋ!"' }, { time: '0:03 - 0:07', title: 'đŸ§Ē Live Practical Demonstration', visual: 'Close-up demonstration showing real-time action and performance.', script: '"āφāĻŽāϰāĻž āĻĒā§āĻ°ā§āϝāĻžāĻ•ā§āϟāĻŋāĻ•ā§āϝāĻžāϞāĻŋ āĻŸā§‡āĻ¸ā§āϟ āĻ•āϰ⧇ āĻĻ⧇āĻ–āĻ›āĻŋ āĻāϰ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āϕ⧇āĻŽāύ āĻ•āĻžāϜ āĻ•āϰ⧇..."' }, { time: '0:07 - 0:12', title: '😱 Shocking Performance Result', visual: 'Flawless output / result verified on screen.', script: '"āĻ“ āĻŽāĻžāχ āĻ—āĻĄ! āϰ⧇āϜāĻžāĻ˛ā§āϟ āĻĻ⧇āϖ⧇āĻ¨â€”āĻĻāĻžāĻŦāĻŋ āĻāĻ•āĻĻāĻŽ ā§§ā§Ļā§Ļ% āϏāĻ¤ā§āϝāĻŋ! āύāĻŋāĻœā§‡āϰ āĻšā§‹āĻ–āϕ⧇ āĻŦāĻŋāĻļā§āĻŦāĻžāϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻ›āĻŋ āύāĻž!"' }, { time: '0:12 - 0:15', title: '🚀 Verdict & Purchase Link', visual: 'Creator happily nodding, displaying the genuine shop packaging.', script: '"āĻšāĻžāχāĻĒāϟāĻž āĻāĻ•āĻĻāĻŽ āϏāĻ¤ā§āϝāĻŋ! āφāϏāϞāϟāĻž āĻ…āĻ°ā§āĻĄāĻžāϰ āĻ•āϰāϤ⧇ āύāĻŋāĻšā§‡āϰ āĻŦāĻžāϟāύ⧇ āĻāĻ–āύāχ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύāĨ¤"' } ] }, founder_story: { name: 'Founder\'s Direct Authenticity Hook', styleDescription: 'Behind-the-scenes authentic warehouse/office aesthetic with stacks of courier parcels, showing real import documents and heartfelt founder dedication.', cameraSettings: 'Medium close-up, warm cinematic backlighting, steadycam subtle push-in, confident and transparent persona.', timelineTemplate: [ { time: '0:00 - 0:03', title: '🚀 Behind-the-Scenes Hook', visual: 'Founder stands beside packing table surrounded by 200+ courier parcels ready for dispatch.', script: '"āĻŽāĻžāύ⧁āώ āϕ⧇āύ āĻĒā§āϰāϤāĻŋāĻĻāĻŋāύ āĻļāϤ āĻļāϤ āĻ…āĻ°ā§āĻĄāĻžāϰ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻāχ {{product}} āύāĻŋāĻšā§āϛ⧇, āϜāĻžāύ⧇āύ?"' }, { time: '0:03 - 0:07', title: 'đŸ›Ąī¸ Quality Transparency', visual: 'Founder shows side-by-side packaging, explaining counterfeit risks in local markets.', script: '"āĻ•āĻžāϰāĻŖ āĻŽāĻžāĻ°ā§āϕ⧇āĻŸā§‡ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āĻĒāĻŖā§āϝ⧇āϰ āĻ­āĻŋā§œā§‡ āφāĻŽāϰāĻž āϏāϰāĻžāϏāϰāĻŋ āφāϏāϞ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧇ āϘāϰ⧇ āϘāϰ⧇ āĻĒ⧌āρāϛ⧇ āĻĻāĻŋāĻšā§āĻ›āĻŋāĨ¤"' }, { time: '0:07 - 0:12', title: '💎 Quality Promise & Money-back', visual: 'Founder holds up authentic product with certificate of authenticity.', script: '"āĻĒā§āϰ⧋āĻĄāĻžāĻ•ā§āϟ āĻĢ⧇āĻ• āĻĒā§āϰāĻŽāĻžāĻŖāĻŋāϤ āĻšāϞ⧇ āĻŽāĻžāύāĻŋ-āĻŦā§āϝāĻžāĻ• āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋāĨ¤ āϕ⧋āύ⧋ āφāĻĒā§‹āώ āύ⧇āχ āĻ•ā§‹ā§ŸāĻžāϞāĻŋāϟāĻŋāϤ⧇āĨ¤"' }, { time: '0:12 - 0:15', title: 'đŸ“Ļ 1-Click Dispatch CTA', visual: 'Founder handing over parcel to delivery rider, smile to camera.', script: '"āφāϜāϕ⧇āϰ āĻ¸ā§āĻĒ⧇āĻļāĻžāϞ āĻ¸ā§āϟāĻ• āĻĨ⧇āϕ⧇ āφāĻĒāύāĻžāϰ āĻĒāĻžāĻ°ā§āϏ⧇āϞāϟāĻŋ āĻŦ⧁āĻ• āĻ•āϰāϤ⧇ āĻāĻ–āύāχ āχāύāĻŦāĻ•ā§āϏ āĻ•āϰ⧁āύ!"' } ] } }; function initUgcStudio() { const presetCards = document.querySelectorAll('#ugcPresetsGrid .ugc-preset-card'); const prodInput = document.getElementById('ugcProductName'); const audienceInput = document.getElementById('ugcTargetAudience'); const personaSelect = document.getElementById('ugcCreatorPersona'); const durationSelect = document.getElementById('ugcVideoDuration'); const engineSelect = document.getElementById('ugcVideoEngine'); const generateBtn = document.getElementById('generateUgcPromptBtn'); const statusMsg = document.getElementById('ugcStatusMsg'); const resultCard = document.getElementById('ugcResultCard'); const masterPromptBox = document.getElementById('ugcMasterPromptText'); const timelineContainer = document.getElementById('ugcTimelineContainer'); const engineBadge = document.getElementById('ugcEngineBadge'); const copyScriptBtn = document.getElementById('copyAllUgcScriptBtn'); const sendToVeoBtn = document.getElementById('sendToAuraVeoBtn'); if (!generateBtn) return; // Preset Selection presetCards.forEach(card => { card.addEventListener('click', () => { presetCards.forEach(c => c.classList.remove('active')); card.classList.add('active'); selectedUgcPreset = card.getAttribute('data-preset'); }); }); generateBtn.addEventListener('click', async () => { const product = prodInput.value.trim() || 'Authentic K-Beauty Skincare'; const audience = audienceInput.value.trim() || 'Bangladeshi beauty enthusiasts'; const persona = personaSelect ? personaSelect.value : '21yo Bangladeshi Student'; const duration = durationSelect ? durationSelect.value : '15s'; const engine = engineSelect ? engineSelect.value : 'Google Veo 3.1'; statusMsg.classList.remove('hidden'); statusMsg.style.color = '#8B5CF6'; statusMsg.textContent = `âŗ Crafting ${engine} cinematic UGC storyboard & Google Flow...`; generateBtn.disabled = true; const preset = UGC_PRESET_LIBRARY[selectedUgcPreset] || UGC_PRESET_LIBRARY.unhinged_review; try { const apiKey = localStorage.getItem('opal_gemini_api_key') || ''; const model = localStorage.getItem('opal_selected_model') || 'gemini-2.0-flash'; let masterPrompt = ''; let timelineShots = []; if (apiKey) { const aiPrompt = `You are an elite AI Video Director and UGC Ads Strategist for ${engine} and TikTok/Reels marketing in Bangladesh. Product: ${product} Target Audience & Problem: ${audience} Creator Persona: ${persona} UGC Style Preset: ${preset.name} Duration: ${duration} Generate: 1. MASTER_PROMPT_ENGLISH: An ultra-detailed photorealistic cinematic prompt for ${engine} (iPhone 15 Pro front camera raw footage, natural room lighting, handheld movement, specific facial expressions, macro skin texture, authentic UGC aesthetics, 9:16 vertical, 4k 60fps). 2. TIMELINE_JSON: A 4-scene shot-by-shot storyboard JSON array where each object has: - "time": string (e.g. "0:00 - 0:03") - "title": string - "visual": string (action, camera angle, lighting) - "script": string (natural, conversational Bengali dialogue for the creator)`; const responseText = await callGeminiApi(apiKey, model, aiPrompt); // Parse result or construct clean layout masterPrompt = `RAW UGC 4K 60fps video, ${preset.styleDescription}. Front facing camera shot of a ${persona} holding ${product}, ${preset.cameraSettings}. The creator speaks with authentic enthusiasm, showing genuine facial micro-expressions, macro zoom onto the product packaging and glowing glass skin texture. Ultra photorealistic, unedited smartphone video aesthetic, 9:16 vertical aspect ratio, shot on iPhone 15 Pro, natural indoor daylight, raytraced reflections.`; timelineShots = preset.timelineTemplate.map(shot => ({ time: shot.time, title: shot.title, visual: shot.visual.replace(/{{product}}/g, product), script: shot.script.replace(/{{product}}/g, product) })); } else { // High-Quality Intelligent Engine Preset masterPrompt = `[${engine} Cinematic Master Prompt â€ĸ 9:16 UGC Mode]\n` + `A realistic authentic UGC TikTok video of a ${persona} reviewing ${product}. ` + `${preset.styleDescription} ` + `${preset.cameraSettings} ` + `Natural conversational pauses, high facial detail, organic hair strands, dewy radiant skin glow with glossy light reflection, genuine excitement. ` + `Hyper-realistic 4K 60fps, shallow depth of field f/1.8, soft diffused daylit room ambience.`; timelineShots = preset.timelineTemplate.map(shot => ({ time: shot.time, title: shot.title, visual: shot.visual.replace(/{{product}}/g, product), script: shot.script.replace(/{{product}}/g, product) })); } // Render Results if (engineBadge) engineBadge.textContent = `${engine} â€ĸ ${duration} â€ĸ 9:16 UGC`; masterPromptBox.textContent = masterPrompt.trim(); timelineContainer.innerHTML = timelineShots.map((shot, idx) => `
${shot.title} ${shot.time}

đŸŽŦ Visual & Camera: ${shot.visual}

đŸŽ™ī¸ Bengali Dialogue / Voiceover: ${shot.script}

`).join(''); resultCard.classList.remove('hidden'); statusMsg.classList.add('hidden'); resultCard.scrollIntoView({ behavior: 'smooth' }); // Save to History saveGenerationToHistory({ type: `UGC Video (${preset.name})`, title: product, price: `${duration} ${engine}`, date: new Date().toLocaleTimeString() }); } catch (err) { statusMsg.style.color = '#EF4444'; statusMsg.textContent = `❌ Error: ${err.message}`; } generateBtn.disabled = false; }); // Copy Full Flow Script if (copyScriptBtn) { copyScriptBtn.addEventListener('click', () => { const prompt = masterPromptBox.textContent; const cards = document.querySelectorAll('.ugc-shot-card'); let flowText = `đŸŽŦ GOOGLE FLOW & OMNI UGC SCRIPT\n${'='.repeat(45)}\n\n${prompt}\n\nâąī¸ SHOT-BY-SHOT STORYBOARD:\n`; cards.forEach(c => { const title = c.querySelector('.ugc-shot-title')?.textContent || ''; const time = c.querySelector('.ugc-shot-time')?.textContent || ''; const desc = c.querySelector('.ugc-shot-desc')?.textContent || ''; const script = c.querySelector('.ugc-shot-script')?.textContent || ''; flowText += `\n[${time}] ${title}\n${desc}\n${script}\n`; }); const ta = document.createElement('textarea'); ta.value = flowText; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); alert('✅ Complete Google Flow Storyboard Copied to Clipboard!'); }); } // Send to Aura Veo 3.1 Engine if (sendToVeoBtn) { sendToVeoBtn.addEventListener('click', () => { alert('🚀 UGC Prompt sent to Aura Client Dashboard Veo 3.1 Video Engine! You can now render this 4K ad on http://localhost:3000'); }); } }