Download index.html from sqibhe/humanizer: direct link, hf CLI and curl.
- Browser
- Download file 62.5 kB
-
https://huggingface.co/spaces/sqibhe/humanizer/resolve/main/index.html
- Command line
-
hf download hf://spaces/sqibhe/humanizer/index.html
-
curl -L -o index.html https://huggingface.co/spaces/sqibhe/humanizer/resolve/main/index.html
62.5 kB
| <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"> | |
| <!-- Settings Panel --> | |
| <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> | |
| <!-- Tabs --> | |
| <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> | |
| <!-- Analyzer Panel --> | |
| <div id="analyzerPanel" class="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Input Section --> | |
| <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> | |
| <!-- Analysis Results --> | |
| <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"> | |
| <!-- Overall Scores --> | |
| <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> | |
| <!-- Detailed Metrics --> | |
| <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> | |
| <!-- Text Analysis --> | |
| <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> | |
| <!-- Key Findings --> | |
| <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"> | |
| <!-- Findings will be added here --> | |
| </div> | |
| </div> | |
| <!-- Common AI Patterns Found --> | |
| <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"> | |
| <!-- Patterns will be added here --> | |
| </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> | |
| <!-- Humanizer Panel --> | |
| <div id="humanizerPanel" class="hidden grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| <!-- Input Section --> | |
| <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> | |
| <!-- Output Section --> | |
| <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> | |
| <!-- Loading and Error Indicators --> | |
| <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() { | |
| // DOM Elements | |
| 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'); | |
| // Settings panel toggle | |
| settingsToggle.addEventListener('click', function() { | |
| settingsPanel.classList.toggle('open'); | |
| settingsIcon.classList.toggle('rotate-180'); | |
| }); | |
| // Load saved settings | |
| 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; | |
| } | |
| } | |
| // Save settings | |
| 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!"); | |
| }); | |
| // Load settings on page load | |
| loadSettings(); | |
| // Tab Switching | |
| 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'); | |
| }); | |
| // Update word count for input | |
| 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`; | |
| }); | |
| // Analyze button click handler | |
| analyzeBtn.addEventListener('click', async function() { | |
| const inputText = aiInput.value.trim(); | |
| if (!inputText) { | |
| showError("Please enter some text to analyze."); | |
| return; | |
| } | |
| // Show loading, hide error | |
| analyzerLoading.classList.remove('hidden'); | |
| errorMessage.classList.add('hidden'); | |
| analyzeBtn.disabled = true; | |
| analyzeBtn.classList.add('opacity-75'); | |
| try { | |
| // Simulate API call with comprehensive analysis | |
| const analysis = await simulateComprehensiveAnalysis(inputText); | |
| // Display results | |
| displayAnalysisResults(analysis); | |
| // Populate humanizer input | |
| 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'); | |
| } | |
| }); | |
| // Proceed to humanize button | |
| proceedToHumanizeBtn.addEventListener('click', function() { | |
| humanizerTab.click(); | |
| }); | |
| // Humanize button click handler | |
| 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; | |
| } | |
| // Check if API key is provided | |
| const apiKey = apiKeyInput.value.trim(); | |
| if (!apiKey) { | |
| showError("Please enter your DeepSeek API key in the settings panel."); | |
| return; | |
| } | |
| // Show loading, hide error | |
| humanizerLoading.classList.remove('hidden'); | |
| errorMessage.classList.add('hidden'); | |
| humanizeBtn.disabled = true; | |
| humanizeBtn.classList.add('opacity-75'); | |
| try { | |
| // Call DeepSeek API to humanize text | |
| const humanizedText = await callDeepSeekApi(inputText, level, tone, apiKey); | |
| if (humanizedText) { | |
| humanOutput.value = humanizedText; | |
| // Update output word count | |
| 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'); | |
| } | |
| }); | |
| // Copy button click handler | |
| copyBtn.addEventListener('click', function() { | |
| if (humanOutput.value) { | |
| humanOutput.select(); | |
| document.execCommand('copy'); | |
| // Show temporary tooltip | |
| 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); | |
| } | |
| }); | |
| // Analyze again button | |
| 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(); | |
| } | |
| }); | |
| // Function to call DeepSeek API | |
| async function callDeepSeekApi(text, level, tone, apiKey) { | |
| const endpoint = apiEndpointInput.value.trim() || 'https://api.deepseek.com/v1'; | |
| // Prepare the prompt based on level and tone | |
| 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 to display analysis results | |
| function displayAnalysisResults(analysis) { | |
| analysisPlaceholder.classList.add('hidden'); | |
| analysisResults.classList.remove('hidden'); | |
| // Animate progress bars | |
| setTimeout(() => { | |
| aiScoreBar.style.width = `${analysis.aiScore}%`; | |
| humanScoreBar.style.width = `${analysis.humanScore}%`; | |
| aiScoreText.textContent = `${analysis.aiScore}%`; | |
| humanScoreText.textContent = `${analysis.humanScore}%`; | |
| // Detailed metrics | |
| 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); | |
| // Add key findings | |
| 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); | |
| }); | |
| // Add AI patterns | |
| 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); | |
| }); | |
| // Display analyzed text with highlights | |
| 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); | |
| }); | |
| } | |
| // Function to simulate comprehensive analysis API call | |
| async function simulateComprehensiveAnalysis(text) { | |
| // Simulate network delay | |
| await new Promise(resolve => setTimeout(resolve, 2000)); | |
| // Calculate metrics based on text characteristics | |
| 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; | |
| // Calculate AI score (0-100) | |
| let aiScore = 0; | |
| let patterns = []; | |
| let textSegments = []; | |
| let findings = []; | |
| // 1. Check for AI keywords | |
| 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}` }); | |
| // Add to text segments | |
| let lastIndex = 0; | |
| let match; | |
| while ((match = regex.exec(text)) !== null) { | |
| // Add text before match | |
| if (match.index > lastIndex) { | |
| textSegments.push({ | |
| text: text.substring(lastIndex, match.index), | |
| class: '' | |
| }); | |
| } | |
| // Add highlighted match | |
| textSegments.push({ | |
| text: match[0], | |
| class: 'highlight-ai', | |
| tooltip: `AI-related keyword detected` | |
| }); | |
| lastIndex = regex.lastIndex; | |
| } | |
| // Add remaining text | |
| if (lastIndex < text.length) { | |
| textSegments.push({ | |
| text: text.substring(lastIndex), | |
| class: '' | |
| }); | |
| } | |
| } | |
| }); | |
| // 2. Check for formal words | |
| 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' | |
| }); | |
| } | |
| // 3. Check for passive voice | |
| 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` }); | |
| } | |
| // 4. Check sentence length variation | |
| 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` }); | |
| } | |
| // 5. Check for repetitive phrasing | |
| 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` }); | |
| } | |
| // 6. Check for personalization | |
| 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` }); | |
| } | |
| // 7. Check for vague generalizations | |
| 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` }); | |
| } | |
| // 8. Check for perfect grammar (lack of colloquialisms) | |
| 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' | |
| }); | |
| } | |
| // Cap at 100 | |
| aiScore = Math.min(100, Math.max(0, aiScore)); | |
| // Human score is inverse of AI score with some randomness | |
| const humanScore = Math.min(100, Math.max(0, 100 - aiScore + (Math.random() * 20 - 10))); | |
| // Calculate perplexity (simulated) | |
| const perplexity = Math.min(100, Math.max(0, | |
| 70 - (aiScore * 0.6) + (Math.random() * 20 - 10) | |
| )); | |
| // Calculate burstiness (simulated) | |
| const burstiness = Math.min(100, Math.max(0, | |
| 60 - (aiScore * 0.5) + (Math.random() * 20 - 10) | |
| )); | |
| // Calculate formality index | |
| const formality = Math.min(100, Math.max(0, | |
| 20 + (aiScore * 0.4) + (Math.random() * 10 - 5) | |
| )); | |
| // Sentence variation score | |
| const sentenceVariation = Math.min(100, Math.max(0, | |
| 40 + (lengthVariation * 60) + (Math.random() * 10 - 5) | |
| )); | |
| // Add positive findings for human-like aspects | |
| 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: '' }] | |
| }; | |
| } | |
| // Helper function to calculate variation coefficient | |
| 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; | |
| } | |
| // Helper function to check for repetitive phrasing | |
| 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> |