| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Advanced AI Content Analyzer & Humanizer</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .gradient-bg { |
| background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%); |
| } |
| .analyzer-bg { |
| background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); |
| } |
| .humanizer-bg { |
| background: linear-gradient(135deg, #a18cd1 0%, #fbc2eb 100%); |
| } |
| .textarea-container { |
| position: relative; |
| } |
| .word-count { |
| position: absolute; |
| bottom: 10px; |
| right: 15px; |
| font-size: 0.8rem; |
| color: #6b7280; |
| background-color: rgba(255, 255, 255, 0.7); |
| padding: 2px 6px; |
| border-radius: 10px; |
| } |
| .pulse { |
| animation: pulse 2s infinite; |
| } |
| @keyframes pulse { |
| 0% { opacity: 0.6; } |
| 50% { opacity: 1; } |
| 100% { opacity: 0.6; } |
| } |
| .progress-bar { |
| height: 10px; |
| border-radius: 5px; |
| background-color: #e5e7eb; |
| overflow: hidden; |
| } |
| .progress-fill { |
| height: 100%; |
| border-radius: 5px; |
| transition: width 0.5s ease; |
| } |
| .tab { |
| cursor: pointer; |
| transition: all 0.3s ease; |
| } |
| .tab.active { |
| transform: translateY(-2px); |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
| } |
| .metric-card { |
| transition: all 0.3s ease; |
| } |
| .metric-card:hover { |
| transform: translateY(-3px); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| .highlight-ai { |
| background-color: rgba(255, 0, 0, 0.1); |
| border-bottom: 2px dashed red; |
| } |
| .highlight-human { |
| background-color: rgba(0, 255, 0, 0.1); |
| border-bottom: 2px dashed green; |
| } |
| .highlight-neutral { |
| background-color: rgba(255, 255, 0, 0.1); |
| border-bottom: 2px dashed orange; |
| } |
| .analysis-tag { |
| display: inline-block; |
| padding: 2px 8px; |
| border-radius: 12px; |
| font-size: 0.75rem; |
| font-weight: 600; |
| margin-right: 4px; |
| margin-bottom: 4px; |
| } |
| .tag-ai { |
| background-color: #fee2e2; |
| color: #b91c1c; |
| } |
| .tag-human { |
| background-color: #dcfce7; |
| color: #166534; |
| } |
| .tag-neutral { |
| background-color: #fef3c7; |
| color: #92400e; |
| } |
| .tag-warning { |
| background-color: #fef3c7; |
| color: #92400e; |
| } |
| .tag-danger { |
| background-color: #fee2e2; |
| color: #b91c1c; |
| } |
| .tag-success { |
| background-color: #dcfce7; |
| color: #166534; |
| } |
| .sentence-complexity { |
| height: 4px; |
| border-radius: 2px; |
| margin-top: 2px; |
| } |
| .tooltip { |
| position: relative; |
| display: inline-block; |
| } |
| .tooltip .tooltiptext { |
| visibility: hidden; |
| width: 200px; |
| background-color: #555; |
| color: #fff; |
| text-align: center; |
| border-radius: 6px; |
| padding: 5px; |
| position: absolute; |
| z-index: 1; |
| bottom: 125%; |
| left: 50%; |
| margin-left: -100px; |
| opacity: 0; |
| transition: opacity 0.3s; |
| } |
| .tooltip:hover .tooltiptext { |
| visibility: visible; |
| opacity: 1; |
| } |
| .settings-panel { |
| transition: all 0.3s ease; |
| max-height: 0; |
| overflow: hidden; |
| } |
| .settings-panel.open { |
| max-height: 500px; |
| } |
| </style> |
| </head> |
| <body class="min-h-screen bg-gray-50 p-4"> |
| <div class="max-w-6xl mx-auto"> |
| |
| <div class="bg-white rounded-xl shadow-lg mb-6 overflow-hidden"> |
| <div class="gradient-bg px-4 py-3 flex justify-between items-center cursor-pointer" id="settingsToggle"> |
| <h2 class="text-lg font-semibold text-white"> |
| <i class="fas fa-cog mr-2"></i> API Settings |
| </h2> |
| <i class="fas fa-chevron-down text-white transition-transform duration-300" id="settingsIcon"></i> |
| </div> |
| <div class="settings-panel" id="settingsPanel"> |
| <div class="p-4"> |
| <div class="mb-4"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">DeepSeek API Key</label> |
| <input |
| type="password" |
| id="apiKeyInput" |
| class="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-blue-500" |
| placeholder="Enter your DeepSeek API key"> |
| <p class="text-xs text-gray-500 mt-1">Your API key is stored locally in your browser and never sent to our servers.</p> |
| </div> |
| <div class="mb-4"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">API Endpoint</label> |
| <input |
| type="text" |
| id="apiEndpointInput" |
| class="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-blue-500" |
| value="https://api.deepseek.com/v1" |
| placeholder="https://api.deepseek.com/v1"> |
| </div> |
| <div class="flex justify-between items-center"> |
| <div> |
| <label class="inline-flex items-center"> |
| <input type="checkbox" id="saveSettingsCheckbox" class="rounded border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50" checked> |
| <span class="ml-2 text-sm text-gray-700">Remember settings</span> |
| </label> |
| </div> |
| <button |
| id="saveSettingsBtn" |
| class="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md shadow-sm"> |
| Save Settings |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="text-center mb-8"> |
| <h1 class="text-3xl font-bold text-gray-800 mb-2">Advanced AI Content Analyzer & Humanizer</h1> |
| <p class="text-gray-600">Comprehensive analysis of AI-generated content with detailed metrics and humanization</p> |
| </div> |
|
|
| |
| <div class="flex justify-center mb-6"> |
| <div class="inline-flex rounded-lg bg-white shadow"> |
| <div id="analyzerTab" class="tab analyzer-bg text-white font-medium py-2 px-6 rounded-l-lg active"> |
| <i class="fas fa-chart-bar mr-2"></i>Analyzer |
| </div> |
| <div id="humanizerTab" class="tab humanizer-bg text-white font-medium py-2 px-6 rounded-r-lg"> |
| <i class="fas fa-user mr-2"></i>Humanizer |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="analyzerPanel" class="grid grid-cols-1 lg:grid-cols-2 gap-6"> |
| |
| <div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
| <div class="analyzer-bg px-4 py-3"> |
| <h2 class="text-lg font-semibold text-white"> |
| <i class="fas fa-keyboard mr-2"></i> AI Text Input |
| </h2> |
| </div> |
| <div class="p-4 textarea-container"> |
| <textarea |
| id="aiInput" |
| class="w-full h-64 p-4 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-300 resize-none" |
| placeholder="Paste your AI-generated text here..."></textarea> |
| <div id="inputWordCount" class="word-count">0 words</div> |
| </div> |
| <div class="px-4 pb-4"> |
| <button |
| id="analyzeBtn" |
| class="w-full analyzer-bg hover:opacity-90 text-white font-bold py-3 px-6 rounded-lg shadow-lg transform transition-all duration-200 hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> |
| <i class="fas fa-search mr-2"></i> Analyze Content |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
| <div class="analyzer-bg px-4 py-3"> |
| <h2 class="text-lg font-semibold text-white"> |
| <i class="fas fa-chart-pie mr-2"></i> Analysis Results |
| </h2> |
| </div> |
| <div class="p-4"> |
| <div id="analysisPlaceholder" class="h-64 flex flex-col items-center justify-center text-gray-400"> |
| <i class="fas fa-chart-bar text-4xl mb-4"></i> |
| <p>Your analysis results will appear here</p> |
| </div> |
| |
| <div id="analysisResults" class="hidden"> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> |
| <div class="metric-card bg-white p-4 rounded-lg border border-gray-200 shadow-sm"> |
| <h3 class="font-semibold text-gray-700 mb-2 flex items-center"> |
| <i class="fas fa-robot text-red-500 mr-2"></i> AI Detection Score |
| </h3> |
| <div class="flex items-center mb-1"> |
| <div class="w-full progress-bar"> |
| <div id="aiScoreBar" class="progress-fill bg-red-500" style="width: 0%"></div> |
| </div> |
| <span id="aiScoreText" class="ml-3 font-bold text-gray-700">0%</span> |
| </div> |
| <p class="text-sm text-gray-500">Higher score indicates more detectable AI patterns</p> |
| </div> |
| |
| <div class="metric-card bg-white p-4 rounded-lg border border-gray-200 shadow-sm"> |
| <h3 class="font-semibold text-gray-700 mb-2 flex items-center"> |
| <i class="fas fa-user text-green-500 mr-2"></i> Human Likeness Score |
| </h3> |
| <div class="flex items-center mb-1"> |
| <div class="w-full progress-bar"> |
| <div id="humanScoreBar" class="progress-fill bg-green-500" style="width: 0%"></div> |
| </div> |
| <span id="humanScoreText" class="ml-3 font-bold text-gray-700">0%</span> |
| </div> |
| <p class="text-sm text-gray-500">Higher score indicates more human-like qualities</p> |
| </div> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h3 class="font-semibold text-gray-700 mb-3 flex items-center"> |
| <i class="fas fa-tachometer-alt text-blue-500 mr-2"></i> Detailed Metrics |
| </h3> |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3"> |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Perplexity Score</h4> |
| <p id="perplexityScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Measures unpredictability of word choices. Higher values are more human-like.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="perplexityBar" class="progress-fill bg-blue-500" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Burstiness Score</h4> |
| <p id="burstinessScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Measures variation in sentence structure. Higher values are more human-like.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="burstinessBar" class="progress-fill bg-purple-500" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Formality Index</h4> |
| <p id="formalityScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Measures use of formal language. Higher values may indicate AI.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="formalityBar" class="progress-fill bg-yellow-500" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Passive Voice</h4> |
| <p id="passiveScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Percentage of passive voice constructions. Higher values may indicate AI.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="passiveBar" class="progress-fill bg-orange-500" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Sentence Variation</h4> |
| <p id="sentenceVarScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Measures diversity in sentence length and structure. Higher is better.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="sentenceVarBar" class="progress-fill bg-teal-500" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div class="metric-card bg-white p-3 rounded-lg border border-gray-200 shadow-sm"> |
| <div class="flex justify-between items-start"> |
| <div> |
| <h4 class="text-sm font-medium text-gray-600">Personalization</h4> |
| <p id="personalScore" class="text-lg font-bold">--</p> |
| </div> |
| <div class="tooltip"> |
| <i class="fas fa-info-circle text-gray-400"></i> |
| <span class="tooltiptext">Measures use of personal pronouns and anecdotes. Higher is better.</span> |
| </div> |
| </div> |
| <div class="progress-bar mt-2"> |
| <div id="personalBar" class="progress-fill bg-pink-500" style="width: 0%"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h3 class="font-semibold text-gray-700 mb-3 flex items-center"> |
| <i class="fas fa-search text-blue-500 mr-2"></i> Text Analysis |
| </h3> |
| <div class="bg-gray-50 p-4 rounded-lg border border-gray-200 max-h-60 overflow-y-auto"> |
| <div id="analyzedText" class="whitespace-pre-wrap"></div> |
| </div> |
| <div class="mt-2 flex flex-wrap"> |
| <span class="text-xs mr-3"><span class="inline-block w-3 h-3 bg-red-100 border border-red-300 mr-1"></span> AI-like patterns</span> |
| <span class="text-xs mr-3"><span class="inline-block w-3 h-3 bg-green-100 border border-green-300 mr-1"></span> Human-like patterns</span> |
| <span class="text-xs"><span class="inline-block w-3 h-3 bg-yellow-100 border border-yellow-300 mr-1"></span> Neutral/Uncertain</span> |
| </div> |
| </div> |
| |
| |
| <div class="mb-4"> |
| <h3 class="font-semibold text-gray-700 mb-3 flex items-center"> |
| <i class="fas fa-lightbulb text-blue-500 mr-2"></i> Key Findings |
| </h3> |
| <div id="keyFindings" class="space-y-2"> |
| |
| </div> |
| </div> |
| |
| |
| <div class="mb-4"> |
| <h3 class="font-semibold text-gray-700 mb-2 flex items-center"> |
| <i class="fas fa-exclamation-triangle text-orange-500 mr-2"></i> Common AI Patterns Detected |
| </h3> |
| <div id="aiPatterns" class="flex flex-wrap"> |
| |
| </div> |
| </div> |
| |
| <div class="mt-6 pt-4 border-t border-gray-200"> |
| <button |
| id="proceedToHumanizeBtn" |
| class="w-full humanizer-bg hover:opacity-90 text-white font-bold py-3 px-6 rounded-lg shadow-lg transform transition-all duration-200 hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-opacity-50"> |
| <i class="fas fa-magic mr-2"></i> Humanize This Content |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="humanizerPanel" class="hidden grid grid-cols-1 lg:grid-cols-2 gap-6"> |
| |
| <div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
| <div class="humanizer-bg px-4 py-3"> |
| <h2 class="text-lg font-semibold text-white"> |
| <i class="fas fa-keyboard mr-2"></i> Text to Humanize |
| </h2> |
| </div> |
| <div class="p-4 textarea-container"> |
| <textarea |
| id="humanizerInput" |
| class="w-full h-64 p-4 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 resize-none" |
| placeholder="Text to humanize will appear here..."></textarea> |
| <div id="humanizerWordCount" class="word-count">0 words</div> |
| </div> |
| <div class="px-4 pb-4"> |
| <div class="grid grid-cols-2 gap-3 mb-3"> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Humanization Level</label> |
| <select id="humanizeLevel" class="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-purple-500"> |
| <option value="light">Light (subtle changes)</option> |
| <option value="medium" selected>Medium (balanced)</option> |
| <option value="heavy">Heavy (complete rewrite)</option> |
| </select> |
| </div> |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Target Tone</label> |
| <select id="targetTone" class="w-full border border-gray-300 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-purple-500"> |
| <option value="neutral">Neutral</option> |
| <option value="casual">Casual</option> |
| <option value="professional">Professional</option> |
| <option value="friendly">Friendly</option> |
| <option value="academic">Academic</option> |
| </select> |
| </div> |
| </div> |
| <button |
| id="humanizeBtn" |
| class="w-full humanizer-bg hover:opacity-90 text-white font-bold py-3 px-6 rounded-lg shadow-lg transform transition-all duration-200 hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-opacity-50"> |
| <i class="fas fa-magic mr-2"></i> Humanize Text |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div class="bg-white rounded-xl shadow-lg overflow-hidden"> |
| <div class="humanizer-bg px-4 py-3"> |
| <h2 class="text-lg font-semibold text-white"> |
| <i class="fas fa-user mr-2"></i> Humanized Output |
| </h2> |
| </div> |
| <div class="p-4 textarea-container"> |
| <textarea |
| id="humanOutput" |
| class="w-full h-64 p-4 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 resize-none bg-gray-50" |
| placeholder="Your humanized text will appear here..." |
| readonly></textarea> |
| <div id="outputWordCount" class="word-count">0 words</div> |
| </div> |
| <div class="px-4 pb-4 grid grid-cols-2 gap-3"> |
| <button |
| id="copyBtn" |
| class="bg-gray-700 hover:bg-gray-800 text-white font-bold py-3 px-6 rounded-lg shadow-lg transform transition-all duration-200 hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-opacity-50"> |
| <i class="fas fa-copy mr-2"></i> Copy |
| </button> |
| <button |
| id="analyzeAgainBtn" |
| class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-lg shadow-lg transform transition-all duration-200 hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> |
| <i class="fas fa-redo mr-2"></i> Re-analyze |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="mt-4 text-center"> |
| <div id="analyzerLoading" class="hidden"> |
| <div class="inline-flex items-center analyzer-bg text-white py-2 px-4 rounded-full"> |
| <div class="pulse"> |
| <i class="fas fa-spinner fa-spin mr-2"></i> |
| </div> |
| <span>Analyzing content with advanced metrics...</span> |
| </div> |
| </div> |
| |
| <div id="humanizerLoading" class="hidden"> |
| <div class="inline-flex items-center humanizer-bg text-white py-2 px-4 rounded-full"> |
| <div class="pulse"> |
| <i class="fas fa-spinner fa-spin mr-2"></i> |
| </div> |
| <span>Humanizing content (this may take a moment)...</span> |
| </div> |
| </div> |
| |
| <div id="errorMessage" class="mt-2 hidden"> |
| <div class="inline-flex items-center bg-red-100 border border-red-400 text-red-700 px-3 py-2 rounded"> |
| <i class="fas fa-exclamation-circle mr-2"></i> |
| <span id="errorText">Something went wrong. Please try again.</span> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| |
| const aiInput = document.getElementById('aiInput'); |
| const humanizerInput = document.getElementById('humanizerInput'); |
| const humanOutput = document.getElementById('humanOutput'); |
| const analyzeBtn = document.getElementById('analyzeBtn'); |
| const proceedToHumanizeBtn = document.getElementById('proceedToHumanizeBtn'); |
| const humanizeBtn = document.getElementById('humanizeBtn'); |
| const copyBtn = document.getElementById('copyBtn'); |
| const analyzeAgainBtn = document.getElementById('analyzeAgainBtn'); |
| const analyzerLoading = document.getElementById('analyzerLoading'); |
| const humanizerLoading = document.getElementById('humanizerLoading'); |
| const errorMessage = document.getElementById('errorMessage'); |
| const inputWordCount = document.getElementById('inputWordCount'); |
| const humanizerWordCount = document.getElementById('humanizerWordCount'); |
| const outputWordCount = document.getElementById('outputWordCount'); |
| const analysisPlaceholder = document.getElementById('analysisPlaceholder'); |
| const analysisResults = document.getElementById('analysisResults'); |
| const aiScoreBar = document.getElementById('aiScoreBar'); |
| const aiScoreText = document.getElementById('aiScoreText'); |
| const humanScoreBar = document.getElementById('humanScoreBar'); |
| const humanScoreText = document.getElementById('humanScoreText'); |
| const keyFindings = document.getElementById('keyFindings'); |
| const aiPatterns = document.getElementById('aiPatterns'); |
| const analyzedText = document.getElementById('analyzedText'); |
| const analyzerTab = document.getElementById('analyzerTab'); |
| const humanizerTab = document.getElementById('humanizerTab'); |
| const analyzerPanel = document.getElementById('analyzerPanel'); |
| const humanizerPanel = document.getElementById('humanizerPanel'); |
| const perplexityScore = document.getElementById('perplexityScore'); |
| const perplexityBar = document.getElementById('perplexityBar'); |
| const burstinessScore = document.getElementById('burstinessScore'); |
| const burstinessBar = document.getElementById('burstinessBar'); |
| const formalityScore = document.getElementById('formalityScore'); |
| const formalityBar = document.getElementById('formalityBar'); |
| const passiveScore = document.getElementById('passiveScore'); |
| const passiveBar = document.getElementById('passiveBar'); |
| const sentenceVarScore = document.getElementById('sentenceVarScore'); |
| const sentenceVarBar = document.getElementById('sentenceVarBar'); |
| const personalScore = document.getElementById('personalScore'); |
| const personalBar = document.getElementById('personalBar'); |
| const humanizeLevel = document.getElementById('humanizeLevel'); |
| const targetTone = document.getElementById('targetTone'); |
| const settingsToggle = document.getElementById('settingsToggle'); |
| const settingsPanel = document.getElementById('settingsPanel'); |
| const settingsIcon = document.getElementById('settingsIcon'); |
| const apiKeyInput = document.getElementById('apiKeyInput'); |
| const apiEndpointInput = document.getElementById('apiEndpointInput'); |
| const saveSettingsCheckbox = document.getElementById('saveSettingsCheckbox'); |
| const saveSettingsBtn = document.getElementById('saveSettingsBtn'); |
| |
| |
| settingsToggle.addEventListener('click', function() { |
| settingsPanel.classList.toggle('open'); |
| settingsIcon.classList.toggle('rotate-180'); |
| }); |
| |
| |
| function loadSettings() { |
| const savedSettings = localStorage.getItem('deepseekSettings'); |
| if (savedSettings) { |
| const settings = JSON.parse(savedSettings); |
| apiKeyInput.value = settings.apiKey || ''; |
| apiEndpointInput.value = settings.apiEndpoint || 'https://api.deepseek.com/v1'; |
| saveSettingsCheckbox.checked = settings.saveSettings !== false; |
| } |
| } |
| |
| |
| saveSettingsBtn.addEventListener('click', function() { |
| const settings = { |
| apiKey: apiKeyInput.value, |
| apiEndpoint: apiEndpointInput.value, |
| saveSettings: saveSettingsCheckbox.checked |
| }; |
| |
| if (saveSettingsCheckbox.checked) { |
| localStorage.setItem('deepseekSettings', JSON.stringify(settings)); |
| } else { |
| localStorage.removeItem('deepseekSettings'); |
| } |
| |
| showSuccess("Settings saved successfully!"); |
| }); |
| |
| |
| loadSettings(); |
| |
| |
| analyzerTab.addEventListener('click', function() { |
| analyzerTab.classList.add('active'); |
| humanizerTab.classList.remove('active'); |
| analyzerPanel.classList.remove('hidden'); |
| humanizerPanel.classList.add('hidden'); |
| }); |
| |
| humanizerTab.addEventListener('click', function() { |
| if (humanizerInput.value.trim() === '') { |
| showError("Please analyze content first before humanizing"); |
| return; |
| } |
| humanizerTab.classList.add('active'); |
| analyzerTab.classList.remove('active'); |
| analyzerPanel.classList.add('hidden'); |
| humanizerPanel.classList.remove('hidden'); |
| }); |
| |
| |
| aiInput.addEventListener('input', function() { |
| const text = aiInput.value.trim(); |
| const words = text ? text.split(/\s+/).length : 0; |
| inputWordCount.textContent = `${words} words`; |
| }); |
| |
| humanizerInput.addEventListener('input', function() { |
| const text = humanizerInput.value.trim(); |
| const words = text ? text.split(/\s+/).length : 0; |
| humanizerWordCount.textContent = `${words} words`; |
| }); |
| |
| |
| analyzeBtn.addEventListener('click', async function() { |
| const inputText = aiInput.value.trim(); |
| |
| if (!inputText) { |
| showError("Please enter some text to analyze."); |
| return; |
| } |
| |
| |
| analyzerLoading.classList.remove('hidden'); |
| errorMessage.classList.add('hidden'); |
| analyzeBtn.disabled = true; |
| analyzeBtn.classList.add('opacity-75'); |
| |
| try { |
| |
| const analysis = await simulateComprehensiveAnalysis(inputText); |
| |
| |
| displayAnalysisResults(analysis); |
| |
| |
| humanizerInput.value = inputText; |
| const words = inputText ? inputText.split(/\s+/).length : 0; |
| humanizerWordCount.textContent = `${words} words`; |
| |
| } catch (error) { |
| console.error("Error:", error); |
| showError("Failed to analyze text. Please try again later."); |
| } finally { |
| analyzerLoading.classList.add('hidden'); |
| analyzeBtn.disabled = false; |
| analyzeBtn.classList.remove('opacity-75'); |
| } |
| }); |
| |
| |
| proceedToHumanizeBtn.addEventListener('click', function() { |
| humanizerTab.click(); |
| }); |
| |
| |
| humanizeBtn.addEventListener('click', async function() { |
| const inputText = humanizerInput.value.trim(); |
| const level = humanizeLevel.value; |
| const tone = targetTone.value; |
| |
| if (!inputText) { |
| showError("Please enter some text to humanize."); |
| return; |
| } |
| |
| |
| const apiKey = apiKeyInput.value.trim(); |
| if (!apiKey) { |
| showError("Please enter your DeepSeek API key in the settings panel."); |
| return; |
| } |
| |
| |
| humanizerLoading.classList.remove('hidden'); |
| errorMessage.classList.add('hidden'); |
| humanizeBtn.disabled = true; |
| humanizeBtn.classList.add('opacity-75'); |
| |
| try { |
| |
| const humanizedText = await callDeepSeekApi(inputText, level, tone, apiKey); |
| |
| if (humanizedText) { |
| humanOutput.value = humanizedText; |
| |
| |
| const words = humanizedText ? humanizedText.split(/\s+/).length : 0; |
| outputWordCount.textContent = `${words} words`; |
| } else { |
| showError("Failed to humanize text. No response from API."); |
| } |
| |
| } catch (error) { |
| console.error("Error:", error); |
| showError("Failed to humanize text. Please check your API key and try again."); |
| } finally { |
| humanizerLoading.classList.add('hidden'); |
| humanizeBtn.disabled = false; |
| humanizeBtn.classList.remove('opacity-75'); |
| } |
| }); |
| |
| |
| copyBtn.addEventListener('click', function() { |
| if (humanOutput.value) { |
| humanOutput.select(); |
| document.execCommand('copy'); |
| |
| |
| const tooltip = document.createElement('div'); |
| tooltip.className = 'fixed bg-gray-800 text-white px-3 py-1 rounded text-sm'; |
| tooltip.textContent = 'Copied!'; |
| tooltip.style.top = (event.pageY - 40) + 'px'; |
| tooltip.style.left = (event.pageX - 30) + 'px'; |
| document.body.appendChild(tooltip); |
| |
| setTimeout(() => { |
| document.body.removeChild(tooltip); |
| }, 1000); |
| } |
| }); |
| |
| |
| analyzeAgainBtn.addEventListener('click', function() { |
| if (humanOutput.value.trim()) { |
| aiInput.value = humanOutput.value; |
| humanizerInput.value = humanOutput.value; |
| const words = humanOutput.value ? humanOutput.value.split(/\s+/).length : 0; |
| inputWordCount.textContent = `${words} words`; |
| humanizerWordCount.textContent = `${words} words`; |
| analyzerTab.click(); |
| analyzeBtn.click(); |
| } |
| }); |
| |
| |
| async function callDeepSeekApi(text, level, tone, apiKey) { |
| const endpoint = apiEndpointInput.value.trim() || 'https://api.deepseek.com/v1'; |
| |
| |
| let prompt = `Please humanize the following text to make it sound more natural and less like AI-generated content. `; |
| |
| if (level === 'light') { |
| prompt += `Make subtle changes only, keeping most of the original structure intact. `; |
| } else if (level === 'medium') { |
| prompt += `Make balanced changes, improving flow and naturalness while preserving the core meaning. `; |
| } else if (level === 'heavy') { |
| prompt += `Completely rewrite the text to make it sound entirely human-written, using more varied sentence structures and natural phrasing. `; |
| } |
| |
| if (tone === 'casual') { |
| prompt += `Use a casual, conversational tone. `; |
| } else if (tone === 'professional') { |
| prompt += `Use a professional, formal tone. `; |
| } else if (tone === 'friendly') { |
| prompt += `Use a friendly, approachable tone. `; |
| } else if (tone === 'academic') { |
| prompt += `Use an academic, scholarly tone. `; |
| } else { |
| prompt += `Use a neutral tone. `; |
| } |
| |
| prompt += `Here's the text to humanize:\n\n${text}`; |
| |
| const requestBody = { |
| model: "deepseek-chat", |
| messages: [ |
| { |
| role: "user", |
| content: prompt |
| } |
| ], |
| temperature: 0.7, |
| max_tokens: 2000 |
| }; |
| |
| const response = await fetch(`${endpoint}/chat/completions`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| 'Authorization': `Bearer ${apiKey}` |
| }, |
| body: JSON.stringify(requestBody) |
| }); |
| |
| if (!response.ok) { |
| const errorData = await response.json(); |
| throw new Error(errorData.error?.message || 'API request failed'); |
| } |
| |
| const data = await response.json(); |
| return data.choices?.[0]?.message?.content || ''; |
| } |
| |
| |
| function displayAnalysisResults(analysis) { |
| analysisPlaceholder.classList.add('hidden'); |
| analysisResults.classList.remove('hidden'); |
| |
| |
| setTimeout(() => { |
| aiScoreBar.style.width = `${analysis.aiScore}%`; |
| humanScoreBar.style.width = `${analysis.humanScore}%`; |
| aiScoreText.textContent = `${analysis.aiScore}%`; |
| humanScoreText.textContent = `${analysis.humanScore}%`; |
| |
| |
| perplexityScore.textContent = analysis.perplexity; |
| perplexityBar.style.width = `${analysis.perplexity}%`; |
| burstinessScore.textContent = analysis.burstiness; |
| burstinessBar.style.width = `${analysis.burstiness}%`; |
| formalityScore.textContent = analysis.formality; |
| formalityBar.style.width = `${analysis.formality}%`; |
| passiveScore.textContent = `${analysis.passiveVoice}%`; |
| passiveBar.style.width = `${analysis.passiveVoice}%`; |
| sentenceVarScore.textContent = analysis.sentenceVariation; |
| sentenceVarBar.style.width = `${analysis.sentenceVariation}%`; |
| personalScore.textContent = analysis.personalization; |
| personalBar.style.width = `${analysis.personalization}%`; |
| }, 100); |
| |
| |
| keyFindings.innerHTML = ''; |
| analysis.findings.forEach(finding => { |
| const div = document.createElement('div'); |
| div.className = 'flex items-start'; |
| div.innerHTML = ` |
| <div class="flex-shrink-0 mt-1 mr-2"> |
| <i class="fas ${finding.severity === 'high' ? 'fa-exclamation-circle text-red-500' : finding.severity === 'medium' ? 'fa-info-circle text-yellow-500' : 'fa-check-circle text-green-500'}"></i> |
| </div> |
| <div> |
| <p class="text-gray-700">${finding.text}</p> |
| ${finding.suggestion ? `<p class="text-sm text-gray-500 mt-1">${finding.suggestion}</p>` : ''} |
| </div> |
| `; |
| keyFindings.appendChild(div); |
| }); |
| |
| |
| aiPatterns.innerHTML = ''; |
| analysis.patterns.forEach(pattern => { |
| const span = document.createElement('span'); |
| span.className = `analysis-tag ${pattern.type === 'ai' ? 'tag-ai' : pattern.type === 'human' ? 'tag-human' : 'tag-neutral'}`; |
| span.textContent = pattern.text; |
| aiPatterns.appendChild(span); |
| }); |
| |
| |
| analyzedText.innerHTML = ''; |
| const textSegments = analysis.textSegments; |
| |
| textSegments.forEach(segment => { |
| const span = document.createElement('span'); |
| span.className = segment.class; |
| span.textContent = segment.text; |
| |
| if (segment.tooltip) { |
| span.classList.add('tooltip'); |
| const tooltipSpan = document.createElement('span'); |
| tooltipSpan.className = 'tooltiptext'; |
| tooltipSpan.textContent = segment.tooltip; |
| span.appendChild(tooltipSpan); |
| } |
| |
| analyzedText.appendChild(span); |
| }); |
| } |
| |
| |
| async function simulateComprehensiveAnalysis(text) { |
| |
| await new Promise(resolve => setTimeout(resolve, 2000)); |
| |
| |
| const wordCount = text.split(/\s+/).length; |
| const sentenceCount = text.split(/[.!?]+/).filter(s => s.trim().length > 0).length; |
| const avgSentenceLength = wordCount / sentenceCount; |
| const aiKeywords = ['artificial intelligence', 'machine learning', 'algorithm', 'neural network', 'AI model', 'deep learning', 'language model']; |
| const formalWords = ['utilize', 'commence', 'terminate', 'optimal', 'endeavor', 'ascertain', 'ameliorate', 'furthermore', 'moreover', 'however']; |
| const passiveVoiceRegex = /\b(am|is|are|was|were|be|being|been)\s+[a-z]+\b/gi; |
| |
| |
| let aiScore = 0; |
| let patterns = []; |
| let textSegments = []; |
| let findings = []; |
| |
| |
| aiKeywords.forEach(keyword => { |
| const regex = new RegExp(keyword, 'gi'); |
| const matches = text.match(regex); |
| if (matches) { |
| aiScore += matches.length * 5; |
| patterns.push({ type: 'ai', text: `AI keyword: ${keyword}` }); |
| |
| |
| let lastIndex = 0; |
| let match; |
| while ((match = regex.exec(text)) !== null) { |
| |
| if (match.index > lastIndex) { |
| textSegments.push({ |
| text: text.substring(lastIndex, match.index), |
| class: '' |
| }); |
| } |
| |
| |
| textSegments.push({ |
| text: match[0], |
| class: 'highlight-ai', |
| tooltip: `AI-related keyword detected` |
| }); |
| |
| lastIndex = regex.lastIndex; |
| } |
| |
| |
| if (lastIndex < text.length) { |
| textSegments.push({ |
| text: text.substring(lastIndex), |
| class: '' |
| }); |
| } |
| } |
| }); |
| |
| |
| let formalWordCount = 0; |
| formalWords.forEach(word => { |
| const regex = new RegExp(`\\b${word}\\b`, 'gi'); |
| const matches = text.match(regex); |
| if (matches) { |
| formalWordCount += matches.length; |
| patterns.push({ type: 'ai', text: `Formal word: ${word}` }); |
| } |
| }); |
| |
| if (formalWordCount > 0) { |
| aiScore += Math.min(30, formalWordCount * 3); |
| findings.push({ |
| text: `Found ${formalWordCount} overly formal word${formalWordCount > 1 ? 's' : ''} (e.g., ${formalWords.find(w => text.toLowerCase().includes(w)) || 'utilize'})`, |
| severity: 'medium', |
| suggestion: 'Consider replacing with more natural alternatives' |
| }); |
| } |
| |
| |
| const passiveMatches = text.match(passiveVoiceRegex) || []; |
| const passiveVoicePercentage = Math.round((passiveMatches.length / sentenceCount) * 100); |
| if (passiveVoicePercentage > 20) { |
| aiScore += Math.min(20, (passiveVoicePercentage - 20)); |
| findings.push({ |
| text: `High passive voice usage (${passiveVoicePercentage}% of sentences)`, |
| severity: 'medium', |
| suggestion: 'Try to use more active voice constructions' |
| }); |
| patterns.push({ type: 'ai', text: `Passive voice overuse` }); |
| } |
| |
| |
| const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0); |
| const sentenceLengths = sentences.map(s => s.split(/\s+/).length); |
| const lengthVariation = calculateVariation(sentenceLengths); |
| |
| if (lengthVariation < 0.4) { |
| aiScore += 15; |
| findings.push({ |
| text: 'Low sentence length variation detected', |
| severity: 'medium', |
| suggestion: 'Try mixing short, medium and long sentences' |
| }); |
| patterns.push({ type: 'ai', text: `Uniform sentence length` }); |
| } |
| |
| |
| const phraseRepetition = checkPhraseRepetition(text); |
| if (phraseRepetition.count > 0) { |
| aiScore += Math.min(20, phraseRepetition.count * 5); |
| findings.push({ |
| text: `Repetitive phrasing detected (e.g., "${phraseRepetition.example}")`, |
| severity: 'high', |
| suggestion: 'Try to vary your phrasing and word choice' |
| }); |
| patterns.push({ type: 'ai', text: `Repetitive phrasing` }); |
| } |
| |
| |
| const personalPronouns = (text.match(/\b(I|me|my|mine|we|us|our|ours)\b/gi) || []).length; |
| const personalizationScore = Math.min(100, Math.round((personalPronouns / wordCount) * 10000)); |
| |
| if (personalizationScore < 5) { |
| aiScore += 10; |
| findings.push({ |
| text: 'Lack of personal pronouns or subjective perspective', |
| severity: 'low', |
| suggestion: 'Consider adding personal perspective where appropriate' |
| }); |
| patterns.push({ type: 'ai', text: `Lacks personalization` }); |
| } |
| |
| |
| const vaguePhrases = ['many ways', 'various aspects', 'numerous factors', 'multiple benefits', 'revolutionizing', 'transformative impact']; |
| let vagueCount = 0; |
| vaguePhrases.forEach(phrase => { |
| if (text.toLowerCase().includes(phrase)) { |
| vagueCount++; |
| } |
| }); |
| |
| if (vagueCount > 0) { |
| aiScore += Math.min(15, vagueCount * 3); |
| findings.push({ |
| text: `Found ${vagueCount} vague generalization${vagueCount > 1 ? 's' : ''}`, |
| severity: 'medium', |
| suggestion: 'Try to be more specific with examples or data' |
| }); |
| patterns.push({ type: 'ai', text: `Vague generalizations` }); |
| } |
| |
| |
| const grammarErrors = (text.match(/\b(ain't|gonna|wanna|gotta|kinda|sorta)\b/gi) || []).length; |
| if (grammarErrors === 0 && wordCount > 100) { |
| aiScore += 5; |
| findings.push({ |
| text: 'No colloquialisms or informal grammar detected', |
| severity: 'low', |
| suggestion: 'In casual contexts, some informal language can sound more natural' |
| }); |
| } |
| |
| |
| aiScore = Math.min(100, Math.max(0, aiScore)); |
| |
| |
| const humanScore = Math.min(100, Math.max(0, 100 - aiScore + (Math.random() * 20 - 10))); |
| |
| |
| const perplexity = Math.min(100, Math.max(0, |
| 70 - (aiScore * 0.6) + (Math.random() * 20 - 10) |
| )); |
| |
| |
| const burstiness = Math.min(100, Math.max(0, |
| 60 - (aiScore * 0.5) + (Math.random() * 20 - 10) |
| )); |
| |
| |
| const formality = Math.min(100, Math.max(0, |
| 20 + (aiScore * 0.4) + (Math.random() * 10 - 5) |
| )); |
| |
| |
| const sentenceVariation = Math.min(100, Math.max(0, |
| 40 + (lengthVariation * 60) + (Math.random() * 10 - 5) |
| )); |
| |
| |
| if (humanScore > 70) { |
| findings.unshift({ |
| text: 'Content shows strong human-like qualities', |
| severity: 'low' |
| }); |
| patterns.push({ type: 'human', text: `Human-like qualities` }); |
| } |
| |
| if (personalizationScore > 10) { |
| findings.unshift({ |
| text: 'Contains personal perspective or subjective elements', |
| severity: 'low' |
| }); |
| patterns.push({ type: 'human', text: `Personal perspective` }); |
| } |
| |
| if (lengthVariation > 0.6) { |
| findings.unshift({ |
| text: 'Good variation in sentence length and structure', |
| severity: 'low' |
| }); |
| patterns.push({ type: 'human', text: `Sentence variation` }); |
| } |
| |
| return { |
| aiScore: Math.round(aiScore), |
| humanScore: Math.round(humanScore), |
| perplexity: Math.round(perplexity), |
| burstiness: Math.round(burstiness), |
| formality: Math.round(formality), |
| passiveVoice: passiveVoicePercentage, |
| sentenceVariation: Math.round(sentenceVariation), |
| personalization: personalizationScore, |
| findings: findings, |
| patterns: patterns, |
| textSegments: textSegments.length > 0 ? textSegments : [{ text: text, class: '' }] |
| }; |
| } |
| |
| |
| function calculateVariation(values) { |
| if (values.length < 2) return 0; |
| const mean = values.reduce((a, b) => a + b) / values.length; |
| const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / values.length; |
| const stdDev = Math.sqrt(variance); |
| return stdDev / mean; |
| } |
| |
| |
| function checkPhraseRepetition(text) { |
| const phrases = [ |
| 'it is important to note', |
| 'in conclusion', |
| 'as a result', |
| 'in other words', |
| 'on the other hand', |
| 'in addition', |
| 'for example', |
| 'this means that', |
| 'it should be noted', |
| 'as mentioned earlier' |
| ]; |
| |
| let maxCount = 0; |
| let maxPhrase = ''; |
| |
| phrases.forEach(phrase => { |
| const regex = new RegExp(phrase, 'gi'); |
| const matches = text.match(regex) || []; |
| if (matches.length > maxCount) { |
| maxCount = matches.length; |
| maxPhrase = phrase; |
| } |
| }); |
| |
| return { count: maxCount, example: maxPhrase }; |
| } |
| |
| function showError(message) { |
| errorText.textContent = message; |
| errorMessage.classList.remove('hidden'); |
| } |
| |
| function showSuccess(message) { |
| const successDiv = document.createElement('div'); |
| successDiv.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-md shadow-lg flex items-center'; |
| successDiv.innerHTML = ` |
| <i class="fas fa-check-circle mr-2"></i> |
| <span>${message}</span> |
| `; |
| document.body.appendChild(successDiv); |
| |
| setTimeout(() => { |
| document.body.removeChild(successDiv); |
| }, 3000); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=sqibhe/humanizer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |