Vidya Rays Automation Toolkit

Powerful automation toolkit for Vidya Rays with AI-powered content analysis, bulk article management, and productivity tools

Size

45.7 KB

Version

1.1.5

Created

Mar 21, 2026

Updated

26 days ago

1// ==UserScript==
2// @name		Vidya Rays Automation Toolkit
3// @description		Powerful automation toolkit for Vidya Rays with AI-powered content analysis, bulk article management, and productivity tools
4// @version		1.1.5
5// @match		https://*.vidyarays.com/*
6// @icon		https://vidyarays.com/wp-content/uploads/fbrfg/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('Vidya Rays Automation Toolkit initialized');
12
13    // Key Generation Automation Class
14    class KeyGenerationAutomator {
15        constructor() {
16            this.isRunning = false;
17            this.currentStep = 0;
18            this.maxSteps = 5;
19            this.adWaitTime = 15000; // 15 seconds
20            this.checkInterval = 500; // Check every 500ms
21            this.statusCallback = null;
22        }
23
24        setStatusCallback(callback) {
25            this.statusCallback = callback;
26        }
27
28        updateStatus(message, type = 'info') {
29            console.log(`[Key Gen] ${message}`);
30            if (this.statusCallback) {
31                this.statusCallback(message, type);
32            }
33        }
34
35        getCurrentStep() {
36            const stepElement = document.querySelector('.steps');
37            if (stepElement) {
38                const stepText = stepElement.textContent.trim();
39                const match = stepText.match(/(\d+)\/(\d+)/);
40                if (match) {
41                    return {
42                        current: parseInt(match[1]),
43                        total: parseInt(match[2])
44                    };
45                }
46            }
47            return null;
48        }
49
50        async clickAd() {
51            this.updateStatus('Looking for ad to click...', 'info');
52            
53            // Try to find and click the ad iframe or container
54            const adContainer = document.querySelector('.ad-content');
55            const adIframe = document.querySelector('#google_ads_iframe_\\/23318727983\\/studyrays_body_0');
56            
57            if (adContainer) {
58                this.updateStatus('Clicking on ad area...', 'info');
59                adContainer.click();
60                
61                // Also try clicking the iframe if it exists
62                if (adIframe) {
63                    adIframe.click();
64                }
65                
66                return true;
67            }
68            
69            this.updateStatus('Ad container not found', 'warning');
70            return false;
71        }
72
73        async waitForTimer(seconds) {
74            this.updateStatus(`Waiting ${seconds} seconds for ad timer...`, 'info');
75            
76            for (let i = seconds; i > 0; i--) {
77                this.updateStatus(`Timer: ${i} seconds remaining...`, 'info');
78                await new Promise(resolve => setTimeout(resolve, 1000));
79                
80                if (!this.isRunning) {
81                    this.updateStatus('Automation stopped by user', 'warning');
82                    return false;
83                }
84            }
85            
86            return true;
87        }
88
89        async clickVerifyButton() {
90            this.updateStatus('Looking for Verify button...', 'info');
91            
92            const verifyBtn = document.getElementById('verifyBtn');
93            if (verifyBtn) {
94                const isVisible = window.getComputedStyle(verifyBtn).display !== 'none';
95                const isEnabled = !verifyBtn.disabled;
96                
97                if (isVisible && isEnabled) {
98                    this.updateStatus('Clicking Verify button...', 'success');
99                    verifyBtn.click();
100                    return true;
101                } else {
102                    this.updateStatus(`Verify button not ready (visible: ${isVisible}, enabled: ${isEnabled})`, 'warning');
103                }
104            } else {
105                this.updateStatus('Verify button not found', 'warning');
106            }
107            
108            return false;
109        }
110
111        async waitForAdOverlay() {
112            this.updateStatus('Waiting for ad overlay to appear...', 'info');
113            
114            let attempts = 0;
115            const maxAttempts = 20; // 10 seconds
116            
117            while (attempts < maxAttempts) {
118                const adOverlay = document.getElementById('adOverlay');
119                if (adOverlay) {
120                    const isVisible = window.getComputedStyle(adOverlay).display !== 'none';
121                    if (isVisible) {
122                        this.updateStatus('Ad overlay detected!', 'success');
123                        return true;
124                    }
125                }
126                
127                await new Promise(resolve => setTimeout(resolve, 500));
128                attempts++;
129                
130                if (!this.isRunning) return false;
131            }
132            
133            this.updateStatus('Ad overlay did not appear', 'warning');
134            return false;
135        }
136
137        async processStep() {
138            const stepInfo = this.getCurrentStep();
139            if (!stepInfo) {
140                this.updateStatus('Could not detect current step', 'error');
141                return false;
142            }
143            
144            this.updateStatus(`Processing Step ${stepInfo.current}/${stepInfo.total}`, 'info');
145            
146            // Wait for ad overlay to be visible
147            const overlayAppeared = await this.waitForAdOverlay();
148            if (!overlayAppeared) {
149                this.updateStatus('Trying to proceed without overlay...', 'warning');
150            }
151            
152            // Click on the ad
153            await this.clickAd();
154            
155            // Wait for the required time (15 seconds)
156            const timerCompleted = await this.waitForTimer(15);
157            if (!timerCompleted) return false;
158            
159            // Additional wait to ensure timer is processed
160            await new Promise(resolve => setTimeout(resolve, 2000));
161            
162            // Click verify button
163            const verifyClicked = await this.clickVerifyButton();
164            if (!verifyClicked) {
165                this.updateStatus('Retrying verify button click...', 'warning');
166                await new Promise(resolve => setTimeout(resolve, 1000));
167                await this.clickVerifyButton();
168            }
169            
170            // Wait for page to process
171            await new Promise(resolve => setTimeout(resolve, 3000));
172            
173            return true;
174        }
175
176        async start() {
177            if (this.isRunning) {
178                this.updateStatus('Automation is already running!', 'warning');
179                return;
180            }
181            
182            this.isRunning = true;
183            this.updateStatus('🚀 Starting key generation automation...', 'success');
184            
185            try {
186                // Check initial step
187                const initialStep = this.getCurrentStep();
188                if (!initialStep) {
189                    this.updateStatus('Key generation page not detected. Please navigate to the key generation page first.', 'error');
190                    this.isRunning = false;
191                    return;
192                }
193                
194                this.updateStatus(`Starting from step ${initialStep.current}/${initialStep.total}`, 'info');
195                
196                // Process each step
197                while (this.isRunning) {
198                    const currentStepInfo = this.getCurrentStep();
199                    
200                    if (!currentStepInfo) {
201                        this.updateStatus('Lost track of steps. Stopping...', 'error');
202                        break;
203                    }
204                    
205                    if (currentStepInfo.current > currentStepInfo.total) {
206                        this.updateStatus('🎉 All steps completed! Key should be generated.', 'success');
207                        break;
208                    }
209                    
210                    // Process current step
211                    const success = await this.processStep();
212                    
213                    if (!success) {
214                        this.updateStatus('Step processing failed. Stopping automation.', 'error');
215                        break;
216                    }
217                    
218                    // Check if we've moved to the next step
219                    await new Promise(resolve => setTimeout(resolve, 2000));
220                    const newStepInfo = this.getCurrentStep();
221                    
222                    if (newStepInfo && newStepInfo.current === currentStepInfo.current) {
223                        this.updateStatus('Step did not advance. Retrying...', 'warning');
224                        await new Promise(resolve => setTimeout(resolve, 2000));
225                    }
226                    
227                    // Safety check - if we're on step 5/5 and verify button is gone, we're done
228                    if (currentStepInfo.current === 5) {
229                        const verifyBtn = document.getElementById('verifyBtn');
230                        if (!verifyBtn || window.getComputedStyle(verifyBtn).display === 'none') {
231                            this.updateStatus('🎉 Key generation completed!', 'success');
232                            break;
233                        }
234                    }
235                }
236                
237            } catch (error) {
238                console.error('Automation error:', error);
239                this.updateStatus(`Error: ${error.message}`, 'error');
240            } finally {
241                this.isRunning = false;
242                this.updateStatus('Automation stopped.', 'info');
243            }
244        }
245
246        stop() {
247            if (this.isRunning) {
248                this.updateStatus('Stopping automation...', 'warning');
249                this.isRunning = false;
250            }
251        }
252    }
253
254    // Article Management Functions
255    class ArticleManager {
256        constructor() {
257            this.articles = [];
258        }
259
260        async collectAllArticles() {
261            console.log('Collecting all articles from page...');
262            const articleElements = document.querySelectorAll('.entry-list-item article.entry');
263            this.articles = [];
264
265            articleElements.forEach((article, index) => {
266                const titleElement = article.querySelector('.entry-title a');
267                const excerptElement = article.querySelector('.entry-summary, .entry-content');
268                const imageElement = article.querySelector('.post-thumbnail img');
269                const categoriesElements = article.querySelectorAll('.entry-taxonomies .category-links a');
270                const tagsElements = article.querySelectorAll('.entry-taxonomies .tag-links a');
271
272                const articleData = {
273                    index: index + 1,
274                    title: titleElement?.textContent?.trim() || 'No title',
275                    url: titleElement?.href || '',
276                    excerpt: excerptElement?.textContent?.trim()?.substring(0, 200) || 'No excerpt',
277                    image: imageElement?.src || '',
278                    categories: Array.from(categoriesElements).map(a => a.textContent.trim()),
279                    tags: Array.from(tagsElements).map(a => a.textContent.trim()),
280                    element: article
281                };
282
283                this.articles.push(articleData);
284            });
285
286            console.log(`Collected ${this.articles.length} articles`);
287            return this.articles;
288        }
289
290        async exportArticlesToJSON() {
291            await this.collectAllArticles();
292            const exportData = {
293                exportDate: new Date().toISOString(),
294                totalArticles: this.articles.length,
295                articles: this.articles.map(a => ({
296                    title: a.title,
297                    url: a.url,
298                    excerpt: a.excerpt,
299                    categories: a.categories,
300                    tags: a.tags,
301                    image: a.image
302                }))
303            };
304
305            const jsonString = JSON.stringify(exportData, null, 2);
306            const blob = new Blob([jsonString], { type: 'application/json' });
307            const url = URL.createObjectURL(blob);
308            const a = document.createElement('a');
309            a.href = url;
310            a.download = `vidyarays-articles-${new Date().toISOString().split('T')[0]}.json`;
311            document.body.appendChild(a);
312            a.click();
313            document.body.removeChild(a);
314            URL.revokeObjectURL(url);
315
316            console.log('Articles exported to JSON');
317            return exportData;
318        }
319
320        async exportArticlesToCSV() {
321            await this.collectAllArticles();
322            const headers = ['Index', 'Title', 'URL', 'Categories', 'Tags', 'Excerpt'];
323            const rows = this.articles.map(a => [
324                a.index,
325                `"${a.title.replace(/"/g, '""')}"`,
326                a.url,
327                `"${a.categories.join(', ')}"`,
328                `"${a.tags.join(', ')}"`,
329                `"${a.excerpt.replace(/"/g, '""')}"`
330            ]);
331
332            const csvContent = [headers.join(','), ...rows.map(r => r.join(','))].join('\n');
333            const blob = new Blob([csvContent], { type: 'text/csv' });
334            const url = URL.createObjectURL(blob);
335            const a = document.createElement('a');
336            a.href = url;
337            a.download = `vidyarays-articles-${new Date().toISOString().split('T')[0]}.csv`;
338            document.body.appendChild(a);
339            a.click();
340            document.body.removeChild(a);
341            URL.revokeObjectURL(url);
342
343            console.log('Articles exported to CSV');
344        }
345
346        async copyArticleTitles() {
347            await this.collectAllArticles();
348            const titles = this.articles.map(a => a.title).join('\n');
349            await GM.setClipboard(titles);
350            console.log('Article titles copied to clipboard');
351            return titles;
352        }
353
354        async copyArticleURLs() {
355            await this.collectAllArticles();
356            const urls = this.articles.map(a => a.url).join('\n');
357            await GM.setClipboard(urls);
358            console.log('Article URLs copied to clipboard');
359            return urls;
360        }
361
362        filterByCategory(category) {
363            return this.articles.filter(a => 
364                a.categories.some(cat => cat.toLowerCase().includes(category.toLowerCase()))
365            );
366        }
367
368        filterByTag(tag) {
369            return this.articles.filter(a => 
370                a.tags.some(t => t.toLowerCase().includes(tag.toLowerCase()))
371            );
372        }
373
374        async highlightArticlesByKeyword(keyword) {
375            await this.collectAllArticles();
376            const matchingArticles = this.articles.filter(a => 
377                a.title.toLowerCase().includes(keyword.toLowerCase()) ||
378                a.excerpt.toLowerCase().includes(keyword.toLowerCase())
379            );
380
381            // Remove previous highlights
382            document.querySelectorAll('.vr-toolkit-highlight').forEach(el => {
383                el.classList.remove('vr-toolkit-highlight');
384            });
385
386            // Add highlights
387            matchingArticles.forEach(article => {
388                article.element.classList.add('vr-toolkit-highlight');
389            });
390
391            console.log(`Highlighted ${matchingArticles.length} articles matching "${keyword}"`);
392            return matchingArticles;
393        }
394    }
395
396    // AI-Powered Content Analysis
397    class AIContentAnalyzer {
398        async analyzeArticle(articleData) {
399            console.log('Analyzing article with AI:', articleData.title);
400            
401            try {
402                const analysis = await RM.aiCall(
403                    `Analyze this article and provide insights:\n\nTitle: ${articleData.title}\n\nExcerpt: ${articleData.excerpt}\n\nCategories: ${articleData.categories.join(', ')}\n\nProvide a comprehensive analysis.`,
404                    {
405                        type: 'json_schema',
406                        json_schema: {
407                            name: 'article_analysis',
408                            schema: {
409                                type: 'object',
410                                properties: {
411                                    sentiment: { 
412                                        type: 'string', 
413                                        enum: ['positive', 'neutral', 'negative'] 
414                                    },
415                                    mainTopics: { 
416                                        type: 'array', 
417                                        items: { type: 'string' } 
418                                    },
419                                    targetAudience: { type: 'string' },
420                                    readabilityLevel: { 
421                                        type: 'string',
422                                        enum: ['beginner', 'intermediate', 'advanced']
423                                    },
424                                    keyInsights: { 
425                                        type: 'array', 
426                                        items: { type: 'string' } 
427                                    },
428                                    suggestedImprovements: { 
429                                        type: 'array', 
430                                        items: { type: 'string' } 
431                                    },
432                                    seoScore: { 
433                                        type: 'number',
434                                        minimum: 0,
435                                        maximum: 10
436                                    }
437                                },
438                                required: ['sentiment', 'mainTopics', 'targetAudience', 'readabilityLevel']
439                            }
440                        }
441                    }
442                );
443
444                console.log('AI Analysis complete:', analysis);
445                return analysis;
446            } catch (error) {
447                console.error('AI analysis failed:', error);
448                throw error;
449            }
450        }
451
452        async generateSummary(articleData) {
453            console.log('Generating AI summary for:', articleData.title);
454            
455            try {
456                const summary = await RM.aiCall(
457                    `Create a concise 2-3 sentence summary of this article:\n\nTitle: ${articleData.title}\n\nExcerpt: ${articleData.excerpt}`
458                );
459
460                console.log('AI Summary generated');
461                return summary;
462            } catch (error) {
463                console.error('AI summary generation failed:', error);
464                throw error;
465            }
466        }
467
468        async suggestTags(articleData) {
469            console.log('Generating tag suggestions for:', articleData.title);
470            
471            try {
472                const tagSuggestions = await RM.aiCall(
473                    `Suggest 5-10 relevant tags for this article:\n\nTitle: ${articleData.title}\n\nExcerpt: ${articleData.excerpt}\n\nExisting tags: ${articleData.tags.join(', ')}`,
474                    {
475                        type: 'json_schema',
476                        json_schema: {
477                            name: 'tag_suggestions',
478                            schema: {
479                                type: 'object',
480                                properties: {
481                                    suggestedTags: { 
482                                        type: 'array', 
483                                        items: { type: 'string' } 
484                                    },
485                                    reasoning: { type: 'string' }
486                                },
487                                required: ['suggestedTags']
488                            }
489                        }
490                    }
491                );
492
493                console.log('Tag suggestions generated:', tagSuggestions);
494                return tagSuggestions;
495            } catch (error) {
496                console.error('Tag suggestion failed:', error);
497                throw error;
498            }
499        }
500
501        async batchAnalyzeArticles(articles) {
502            console.log(`Starting batch analysis of ${articles.length} articles...`);
503            const results = [];
504
505            for (let i = 0; i < articles.length; i++) {
506                try {
507                    const analysis = await this.analyzeArticle(articles[i]);
508                    results.push({
509                        article: articles[i],
510                        analysis: analysis
511                    });
512                    console.log(`Analyzed ${i + 1}/${articles.length} articles`);
513                } catch (error) {
514                    console.error(`Failed to analyze article ${i + 1}:`, error);
515                    results.push({
516                        article: articles[i],
517                        error: error.message
518                    });
519                }
520            }
521
522            return results;
523        }
524    }
525
526    // UI Panel Manager
527    class ToolkitUI {
528        constructor(articleManager, aiAnalyzer, keyGenAutomator) {
529            this.articleManager = articleManager;
530            this.aiAnalyzer = aiAnalyzer;
531            this.keyGenAutomator = keyGenAutomator;
532            this.panel = null;
533            this.isVisible = false;
534            
535            // Set up key gen status callback
536            this.keyGenAutomator.setStatusCallback((message, type) => {
537                this.showKeyGenStatus(message, type);
538            });
539        }
540
541        createPanel() {
542            // Create panel container
543            this.panel = document.createElement('div');
544            this.panel.id = 'vr-automation-toolkit';
545            this.panel.innerHTML = `
546                <div class="vr-toolkit-header">
547                    <h3>🚀 Vidya Rays Toolkit</h3>
548                    <button class="vr-toolkit-close" title="Close">×</button>
549                </div>
550                <div class="vr-toolkit-content">
551                    <div class="vr-toolkit-section">
552                        <h4>🔑 Key Generation Automation</h4>
553                        <button class="vr-toolkit-btn vr-toolkit-btn-keygen" data-action="start-keygen">Start Auto Key Generation</button>
554                        <button class="vr-toolkit-btn vr-toolkit-btn-stop" data-action="stop-keygen">Stop Automation</button>
555                        <div id="vr-keygen-status" class="vr-keygen-status">
556                            <p>Click "Start Auto Key Generation" to begin automated key generation process.</p>
557                        </div>
558                    </div>
559                
560                    <div class="vr-toolkit-section">
561                        <h4>📊 Article Management</h4>
562                        <button class="vr-toolkit-btn" data-action="collect">Collect All Articles</button>
563                        <button class="vr-toolkit-btn" data-action="export-json">Export to JSON</button>
564                        <button class="vr-toolkit-btn" data-action="export-csv">Export to CSV</button>
565                        <button class="vr-toolkit-btn" data-action="copy-titles">Copy Titles</button>
566                        <button class="vr-toolkit-btn" data-action="copy-urls">Copy URLs</button>
567                    </div>
568                    
569                    <div class="vr-toolkit-section">
570                        <h4>🔍 Search & Filter</h4>
571                        <input type="text" class="vr-toolkit-input" id="vr-keyword-input" placeholder="Enter keyword to highlight...">
572                        <button class="vr-toolkit-btn" data-action="highlight">Highlight Articles</button>
573                        <button class="vr-toolkit-btn" data-action="clear-highlight">Clear Highlights</button>
574                    </div>
575                    
576                    <div class="vr-toolkit-section">
577                        <h4>🤖 AI Analysis</h4>
578                        <button class="vr-toolkit-btn vr-toolkit-btn-ai" data-action="analyze-first">Analyze First Article</button>
579                        <button class="vr-toolkit-btn vr-toolkit-btn-ai" data-action="batch-analyze">Batch Analyze (First 3)</button>
580                        <button class="vr-toolkit-btn vr-toolkit-btn-ai" data-action="generate-summary">Generate Summary</button>
581                    </div>
582                    
583                    <div class="vr-toolkit-section">
584                        <h4>📈 Statistics</h4>
585                        <div id="vr-toolkit-stats" class="vr-toolkit-stats">
586                            <p>Click "Collect All Articles" to see stats</p>
587                        </div>
588                    </div>
589                    
590                    <div class="vr-toolkit-section">
591                        <h4>📋 Results</h4>
592                        <div id="vr-toolkit-results" class="vr-toolkit-results">
593                            <p>Results will appear here...</p>
594                        </div>
595                    </div>
596                </div>
597            `;
598
599            document.body.appendChild(this.panel);
600            this.attachEventListeners();
601            console.log('Toolkit UI panel created');
602        }
603
604        attachEventListeners() {
605            // Close button
606            this.panel.querySelector('.vr-toolkit-close').addEventListener('click', () => {
607                this.togglePanel();
608            });
609
610            // Action buttons
611            this.panel.querySelectorAll('[data-action]').forEach(btn => {
612                btn.addEventListener('click', async (e) => {
613                    const action = e.target.dataset.action;
614                    await this.handleAction(action, e.target);
615                });
616            });
617        }
618
619        async handleAction(action, button) {
620            // Handle key generation actions separately (no loading state)
621            if (action === 'start-keygen') {
622                this.keyGenAutomator.start();
623                return;
624            }
625            
626            if (action === 'stop-keygen') {
627                this.keyGenAutomator.stop();
628                return;
629            }
630            
631            // For other actions, show loading state
632            const originalText = button.textContent;
633            button.textContent = '⏳ Processing...';
634            button.disabled = true;
635
636            try {
637                switch (action) {
638                case 'collect':
639                    await this.handleCollectArticles();
640                    break;
641                case 'export-json':
642                    await this.articleManager.exportArticlesToJSON();
643                    this.showResult('✅ Articles exported to JSON successfully!');
644                    break;
645                case 'export-csv':
646                    await this.articleManager.exportArticlesToCSV();
647                    this.showResult('✅ Articles exported to CSV successfully!');
648                    break;
649                case 'copy-titles':
650                    await this.articleManager.copyArticleTitles();
651                    this.showResult('✅ Article titles copied to clipboard!');
652                    break;
653                case 'copy-urls':
654                    await this.articleManager.copyArticleURLs();
655                    this.showResult('✅ Article URLs copied to clipboard!');
656                    break;
657                case 'highlight':
658                    await this.handleHighlight();
659                    break;
660                case 'clear-highlight':
661                    document.querySelectorAll('.vr-toolkit-highlight').forEach(el => {
662                        el.classList.remove('vr-toolkit-highlight');
663                    });
664                    this.showResult('✅ Highlights cleared!');
665                    break;
666                case 'analyze-first':
667                    await this.handleAnalyzeFirst();
668                    break;
669                case 'batch-analyze':
670                    await this.handleBatchAnalyze();
671                    break;
672                case 'generate-summary':
673                    await this.handleGenerateSummary();
674                    break;
675                }
676            } catch (error) {
677                console.error('Action failed:', error);
678                this.showResult(`❌ Error: ${error.message}`);
679            } finally {
680                button.textContent = originalText;
681                button.disabled = false;
682            }
683        }
684
685        showKeyGenStatus(message, type) {
686            const statusDiv = document.getElementById('vr-keygen-status');
687            if (!statusDiv) return;
688            
689            const timestamp = new Date().toLocaleTimeString();
690            const icon = type === 'success' ? '✅' : type === 'error' ? '❌' : type === 'warning' ? '⚠️' : 'ℹ️';
691            const colorClass = type === 'success' ? 'status-success' : type === 'error' ? 'status-error' : type === 'warning' ? 'status-warning' : 'status-info';
692            
693            const statusLine = document.createElement('p');
694            statusLine.className = `status-line ${colorClass}`;
695            statusLine.innerHTML = `<span class="status-time">[${timestamp}]</span> ${icon} ${message}`;
696            
697            statusDiv.appendChild(statusLine);
698            
699            // Keep only last 10 messages
700            while (statusDiv.children.length > 10) {
701                statusDiv.removeChild(statusDiv.firstChild);
702            }
703            
704            // Auto-scroll to bottom
705            statusDiv.scrollTop = statusDiv.scrollHeight;
706        }
707
708        async handleCollectArticles() {
709            const articles = await this.articleManager.collectAllArticles();
710            
711            // Update statistics
712            const categories = {};
713            const tags = {};
714            
715            articles.forEach(article => {
716                article.categories.forEach(cat => {
717                    categories[cat] = (categories[cat] || 0) + 1;
718                });
719                article.tags.forEach(tag => {
720                    tags[tag] = (tags[tag] || 0) + 1;
721                });
722            });
723
724            const statsHTML = `
725                <p><strong>Total Articles:</strong> ${articles.length}</p>
726                <p><strong>Categories:</strong> ${Object.keys(categories).length}</p>
727                <p><strong>Top Categories:</strong> ${Object.entries(categories).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([cat, count]) => `${cat} (${count})`).join(', ')}</p>
728                <p><strong>Total Tags:</strong> ${Object.keys(tags).length}</p>
729            `;
730
731            document.getElementById('vr-toolkit-stats').innerHTML = statsHTML;
732            this.showResult(`✅ Collected ${articles.length} articles successfully!`);
733        }
734
735        async handleHighlight() {
736            const keyword = document.getElementById('vr-keyword-input').value.trim();
737            if (!keyword) {
738                this.showResult('⚠️ Please enter a keyword to highlight');
739                return;
740            }
741
742            const matches = await this.articleManager.highlightArticlesByKeyword(keyword);
743            this.showResult(`✅ Highlighted ${matches.length} articles matching "${keyword}"`);
744        }
745
746        async handleAnalyzeFirst() {
747            await this.articleManager.collectAllArticles();
748            if (this.articleManager.articles.length === 0) {
749                this.showResult('⚠️ No articles found on this page');
750                return;
751            }
752
753            const firstArticle = this.articleManager.articles[0];
754            const analysis = await this.aiAnalyzer.analyzeArticle(firstArticle);
755
756            const resultHTML = `
757                <h5>📊 Analysis: ${firstArticle.title}</h5>
758                <p><strong>Sentiment:</strong> ${analysis.sentiment}</p>
759                <p><strong>Target Audience:</strong> ${analysis.targetAudience}</p>
760                <p><strong>Readability:</strong> ${analysis.readabilityLevel}</p>
761                <p><strong>SEO Score:</strong> ${analysis.seoScore || 'N/A'}/10</p>
762                <p><strong>Main Topics:</strong> ${analysis.mainTopics.join(', ')}</p>
763                ${analysis.keyInsights ? `<p><strong>Key Insights:</strong></p><ul>${analysis.keyInsights.map(i => `<li>${i}</li>`).join('')}</ul>` : ''}
764            `;
765
766            this.showResult(resultHTML);
767        }
768
769        async handleBatchAnalyze() {
770            await this.articleManager.collectAllArticles();
771            const articlesToAnalyze = this.articleManager.articles.slice(0, 3);
772            
773            if (articlesToAnalyze.length === 0) {
774                this.showResult('⚠️ No articles found on this page');
775                return;
776            }
777
778            this.showResult(`🔄 Analyzing ${articlesToAnalyze.length} articles... This may take a moment.`);
779            
780            const results = await this.aiAnalyzer.batchAnalyzeArticles(articlesToAnalyze);
781            
782            const resultHTML = `
783                <h5>📊 Batch Analysis Results</h5>
784                ${results.map((result, index) => `
785                    <div class="vr-analysis-result">
786                        <h6>${index + 1}. ${result.article.title}</h6>
787                        ${result.error ? `<p class="error">❌ ${result.error}</p>` : `
788                            <p><strong>Sentiment:</strong> ${result.analysis.sentiment} | 
789                            <strong>Level:</strong> ${result.analysis.readabilityLevel} | 
790                            <strong>SEO:</strong> ${result.analysis.seoScore || 'N/A'}/10</p>
791                            <p><strong>Topics:</strong> ${result.analysis.mainTopics.join(', ')}</p>
792                        `}
793                    </div>
794                `).join('')}
795            `;
796
797            this.showResult(resultHTML);
798        }
799
800        async handleGenerateSummary() {
801            await this.articleManager.collectAllArticles();
802            if (this.articleManager.articles.length === 0) {
803                this.showResult('⚠️ No articles found on this page');
804                return;
805            }
806
807            const firstArticle = this.articleManager.articles[0];
808            const summary = await this.aiAnalyzer.generateSummary(firstArticle);
809
810            const resultHTML = `
811                <h5>📝 AI Summary</h5>
812                <h6>${firstArticle.title}</h6>
813                <p>${summary}</p>
814            `;
815
816            this.showResult(resultHTML);
817        }
818
819        showResult(html) {
820            const resultsDiv = document.getElementById('vr-toolkit-results');
821            resultsDiv.innerHTML = html;
822        }
823
824        togglePanel() {
825            this.isVisible = !this.isVisible;
826            this.panel.style.display = this.isVisible ? 'block' : 'none';
827        }
828
829        createToggleButton() {
830            const button = document.createElement('button');
831            button.id = 'vr-toolkit-toggle';
832            button.innerHTML = '🚀';
833            button.title = 'Open Vidya Rays Automation Toolkit';
834            button.addEventListener('click', () => this.togglePanel());
835            document.body.appendChild(button);
836            console.log('Toolkit toggle button created');
837        }
838
839        addStyles() {
840            const styles = `
841                #vr-automation-toolkit {
842                    position: fixed;
843                    top: 50%;
844                    right: 20px;
845                    transform: translateY(-50%);
846                    width: 420px;
847                    max-height: 90vh;
848                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
849                    border-radius: 16px;
850                    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
851                    z-index: 999999;
852                    display: none;
853                    overflow: hidden;
854                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
855                }
856
857                .vr-toolkit-header {
858                    background: rgba(255, 255, 255, 0.1);
859                    padding: 16px 20px;
860                    display: flex;
861                    justify-content: space-between;
862                    align-items: center;
863                    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
864                }
865
866                .vr-toolkit-header h3 {
867                    margin: 0;
868                    color: #ffffff;
869                    font-size: 18px;
870                    font-weight: 600;
871                }
872
873                .vr-toolkit-close {
874                    background: rgba(255, 255, 255, 0.2);
875                    border: none;
876                    color: #ffffff;
877                    font-size: 24px;
878                    width: 32px;
879                    height: 32px;
880                    border-radius: 50%;
881                    cursor: pointer;
882                    display: flex;
883                    align-items: center;
884                    justify-content: center;
885                    transition: all 0.3s ease;
886                }
887
888                .vr-toolkit-close:hover {
889                    background: rgba(255, 255, 255, 0.3);
890                    transform: rotate(90deg);
891                }
892
893                .vr-toolkit-content {
894                    padding: 20px;
895                    max-height: calc(90vh - 70px);
896                    overflow-y: auto;
897                    background: #ffffff;
898                }
899
900                .vr-toolkit-content::-webkit-scrollbar {
901                    width: 8px;
902                }
903
904                .vr-toolkit-content::-webkit-scrollbar-track {
905                    background: #f1f1f1;
906                }
907
908                .vr-toolkit-content::-webkit-scrollbar-thumb {
909                    background: #667eea;
910                    border-radius: 4px;
911                }
912
913                .vr-toolkit-section {
914                    margin-bottom: 24px;
915                    padding-bottom: 20px;
916                    border-bottom: 1px solid #e0e0e0;
917                }
918
919                .vr-toolkit-section:last-child {
920                    border-bottom: none;
921                }
922
923                .vr-toolkit-section h4 {
924                    margin: 0 0 12px 0;
925                    color: #333333;
926                    font-size: 14px;
927                    font-weight: 600;
928                    text-transform: uppercase;
929                    letter-spacing: 0.5px;
930                }
931
932                .vr-toolkit-btn {
933                    width: 100%;
934                    padding: 10px 16px;
935                    margin-bottom: 8px;
936                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
937                    color: #ffffff;
938                    border: none;
939                    border-radius: 8px;
940                    font-size: 13px;
941                    font-weight: 500;
942                    cursor: pointer;
943                    transition: all 0.3s ease;
944                    box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
945                }
946
947                .vr-toolkit-btn:hover {
948                    transform: translateY(-2px);
949                    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
950                }
951
952                .vr-toolkit-btn:active {
953                    transform: translateY(0);
954                }
955
956                .vr-toolkit-btn:disabled {
957                    opacity: 0.6;
958                    cursor: not-allowed;
959                    transform: none;
960                }
961
962                .vr-toolkit-btn-keygen {
963                    background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
964                    box-shadow: 0 2px 8px rgba(17, 153, 142, 0.3);
965                }
966
967                .vr-toolkit-btn-keygen:hover {
968                    box-shadow: 0 4px 12px rgba(17, 153, 142, 0.4);
969                }
970
971                .vr-toolkit-btn-stop {
972                    background: linear-gradient(135deg, #ee0979 0%, #ff6a00 100%);
973                    box-shadow: 0 2px 8px rgba(238, 9, 121, 0.3);
974                }
975
976                .vr-toolkit-btn-stop:hover {
977                    box-shadow: 0 4px 12px rgba(238, 9, 121, 0.4);
978                }
979
980                .vr-toolkit-btn-ai {
981                    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
982                    box-shadow: 0 2px 8px rgba(245, 87, 108, 0.3);
983                }
984
985                .vr-toolkit-btn-ai:hover {
986                    box-shadow: 0 4px 12px rgba(245, 87, 108, 0.4);
987                }
988
989                .vr-toolkit-input {
990                    width: 100%;
991                    padding: 10px 12px;
992                    margin-bottom: 8px;
993                    border: 2px solid #e0e0e0;
994                    border-radius: 8px;
995                    font-size: 13px;
996                    transition: border-color 0.3s ease;
997                    box-sizing: border-box;
998                }
999
1000                .vr-toolkit-input:focus {
1001                    outline: none;
1002                    border-color: #667eea;
1003                }
1004
1005                .vr-keygen-status {
1006                    background: #f8f9fa;
1007                    padding: 12px;
1008                    border-radius: 8px;
1009                    font-size: 12px;
1010                    color: #333333;
1011                    max-height: 200px;
1012                    overflow-y: auto;
1013                    font-family: 'Courier New', monospace;
1014                }
1015
1016                .vr-keygen-status::-webkit-scrollbar {
1017                    width: 6px;
1018                }
1019
1020                .vr-keygen-status::-webkit-scrollbar-thumb {
1021                    background: #667eea;
1022                    border-radius: 3px;
1023                }
1024
1025                .status-line {
1026                    margin: 4px 0;
1027                    padding: 4px 8px;
1028                    border-radius: 4px;
1029                    line-height: 1.4;
1030                }
1031
1032                .status-time {
1033                    color: #666;
1034                    font-size: 11px;
1035                }
1036
1037                .status-success {
1038                    background: #d4edda;
1039                    color: #155724;
1040                }
1041
1042                .status-error {
1043                    background: #f8d7da;
1044                    color: #721c24;
1045                }
1046
1047                .status-warning {
1048                    background: #fff3cd;
1049                    color: #856404;
1050                }
1051
1052                .status-info {
1053                    background: #d1ecf1;
1054                    color: #0c5460;
1055                }
1056
1057                .vr-toolkit-stats {
1058                    background: #f8f9fa;
1059                    padding: 12px;
1060                    border-radius: 8px;
1061                    font-size: 13px;
1062                    color: #333333;
1063                }
1064
1065                .vr-toolkit-stats p {
1066                    margin: 6px 0;
1067                }
1068
1069                .vr-toolkit-results {
1070                    background: #f8f9fa;
1071                    padding: 12px;
1072                    border-radius: 8px;
1073                    font-size: 13px;
1074                    color: #333333;
1075                    max-height: 300px;
1076                    overflow-y: auto;
1077                }
1078
1079                .vr-toolkit-results h5 {
1080                    margin: 0 0 12px 0;
1081                    color: #667eea;
1082                    font-size: 14px;
1083                }
1084
1085                .vr-toolkit-results h6 {
1086                    margin: 8px 0 6px 0;
1087                    color: #333333;
1088                    font-size: 13px;
1089                }
1090
1091                .vr-toolkit-results p {
1092                    margin: 6px 0;
1093                    line-height: 1.5;
1094                }
1095
1096                .vr-toolkit-results ul {
1097                    margin: 6px 0;
1098                    padding-left: 20px;
1099                }
1100
1101                .vr-toolkit-results li {
1102                    margin: 4px 0;
1103                }
1104
1105                .vr-analysis-result {
1106                    background: #ffffff;
1107                    padding: 12px;
1108                    margin-bottom: 12px;
1109                    border-radius: 8px;
1110                    border-left: 4px solid #667eea;
1111                }
1112
1113                .vr-analysis-result .error {
1114                    color: #f5576c;
1115                }
1116
1117                #vr-toolkit-toggle {
1118                    position: fixed;
1119                    bottom: 30px;
1120                    right: 30px;
1121                    width: 60px;
1122                    height: 60px;
1123                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
1124                    border: none;
1125                    border-radius: 50%;
1126                    font-size: 28px;
1127                    cursor: pointer;
1128                    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
1129                    z-index: 999998;
1130                    transition: all 0.3s ease;
1131                }
1132
1133                #vr-toolkit-toggle:hover {
1134                    transform: scale(1.1) rotate(10deg);
1135                    box-shadow: 0 12px 32px rgba(102, 126, 234, 0.5);
1136                }
1137
1138                .vr-toolkit-highlight {
1139                    outline: 3px solid #f5576c !important;
1140                    outline-offset: 4px;
1141                    background: rgba(245, 87, 108, 0.1) !important;
1142                    transition: all 0.3s ease;
1143                }
1144            `;
1145
1146            const styleElement = document.createElement('style');
1147            styleElement.textContent = styles;
1148            document.head.appendChild(styleElement);
1149            console.log('Toolkit styles added');
1150        }
1151    }
1152
1153    // Initialize the toolkit
1154    function init() {
1155        console.log('Initializing Vidya Rays Automation Toolkit...');
1156
1157        // Wait for page to be ready
1158        if (document.readyState === 'loading') {
1159            document.addEventListener('DOMContentLoaded', init);
1160            return;
1161        }
1162
1163        // Create instances
1164        const articleManager = new ArticleManager();
1165        const aiAnalyzer = new AIContentAnalyzer();
1166        const keyGenAutomator = new KeyGenerationAutomator();
1167        const toolkitUI = new ToolkitUI(articleManager, aiAnalyzer, keyGenAutomator);
1168
1169        // Initialize UI
1170        toolkitUI.addStyles();
1171        toolkitUI.createPanel();
1172        toolkitUI.createToggleButton();
1173
1174        console.log('✅ Vidya Rays Automation Toolkit ready!');
1175
1176        // Make instances available globally for debugging
1177        unsafeWindow.VRToolkit = {
1178            articleManager,
1179            aiAnalyzer,
1180            keyGenAutomator,
1181            toolkitUI
1182        };
1183    }
1184
1185    // Start initialization
1186    init();
1187
1188})();