MEO1 commited on
Commit
3ce525b
·
verified ·
1 Parent(s): 108edd7

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +252 -77
index.html CHANGED
@@ -2,51 +2,141 @@
2
  <html lang="tr">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Transformers.js ile Çelişki Tespiti</title>
6
  <style>
7
  body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 2em; background-color: #f9fafb; color: #111827; }
8
- .container { max-width: 800px; margin: 0 auto; background-color: white; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
9
  h1 { color: #374151; }
10
- button { background-color: #3b82f6; color: white; border: none; padding: 10px 15px; border-radius: 5px; cursor: pointer; font-size: 16px; }
11
  button:hover { background-color: #2563eb; }
 
 
12
  #status { margin: 1em 0; padding: 1em; background-color: #eef2ff; border: 1px solid #c7d2fe; border-radius: 5px; display: none; }
13
  .result-item { border: 1px solid #e5e7eb; padding: 15px; margin-top: 15px; border-radius: 5px; }
14
  .result-item p { margin: 0.5em 0; }
15
  .similarity-score { font-weight: bold; color: #ef4444; }
 
 
 
 
 
 
 
16
  </style>
17
  </head>
18
  <body>
19
  <div class="container">
20
- <h1>Metin Analizi ve Çelişki Tespiti</h1>
21
- <p>Analiz etmek için bir metin (<code>.txt</code>) dosyası yükleyin. Tüm işlemler sizin tarayıcınızda, gizliliğiniz korunarak yapılır.</p>
22
 
23
- <input type="file" id="file-input" accept=".txt">
24
- <button id="analyze-button">Analiz Et</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  <div id="status"></div>
 
 
 
27
  <div id="results"></div>
28
  </div>
29
 
30
- <script type="module">
31
- import { pipeline, cos_sim } from 'https://cdn.jsdelivr.net/npm/@xenova/[email protected]';
32
-
33
  const fileInput = document.getElementById('file-input');
34
  const analyzeButton = document.getElementById('analyze-button');
35
  const statusDiv = document.getElementById('status');
36
  const resultsDiv = document.getElementById('results');
 
 
 
 
37
 
38
- // Natural Language Inference (NLI) modeli - çelişki tespiti için daha uygun
39
- statusDiv.style.display = 'block';
40
- statusDiv.textContent = 'Yapay zeka modeli hazırlanıyor... Bu işlem ilk seferde biraz sürebilir.';
41
- const classifier = await pipeline('text-classification', 'Xenova/nli-deberta-v3-small', {
42
- progress_callback: (progress) => {
43
- statusDiv.textContent = `Model indiriliyor... (${Math.round(progress.progress)}%)`;
44
- }
45
- });
46
- statusDiv.textContent = 'Model hazır. Lütfen bir dosya seçip analiz edin.';
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  analyzeButton.addEventListener('click', async () => {
 
 
 
 
 
 
 
50
  if (!fileInput.files || fileInput.files.length === 0) {
51
  alert("Lütfen bir dosya seçin.");
52
  return;
@@ -54,153 +144,238 @@
54
 
55
  const file = fileInput.files[0];
56
  const text = await file.text();
 
57
 
58
  statusDiv.style.display = 'block';
59
  statusDiv.textContent = 'Analiz başladı... Metin cümlelere ayrılıyor.';
60
  resultsDiv.innerHTML = '';
 
 
 
 
61
 
62
  try {
63
- // Metni basit bir yöntemle cümlelere ayır. Daha gelişmiş bir kütüphane kullanılabilir.
64
  let sentences = text.match(/[^.!?]+[.!?]+/g) || [];
65
  if (sentences.length < 2) {
66
  statusDiv.textContent = 'Analiz için en az 2 cümle bulunmalıdır.';
 
67
  return;
68
  }
69
 
70
- // Çok kısa cümleleri filtrele (5 karakterden az)
71
- sentences = sentences.filter(s => s.trim().length > 5);
72
-
73
- // Çok fazla cümle varsa sınırla (performans için)
74
- const maxSentences = 100;
 
 
 
75
  if (sentences.length > maxSentences) {
76
  sentences = sentences.slice(0, maxSentences);
77
- statusDiv.textContent = `Performans için analiz ${maxSentences} cümle ile sınırlandırıldı.`;
78
  await new Promise(resolve => setTimeout(resolve, 2000));
79
  }
80
 
81
- statusDiv.textContent = `Toplam ${sentences.length} cümle bulundu. Çelişki analizi başlıyor...`;
82
 
83
  const potentialContradictions = [];
 
 
84
 
85
- // Her cümleyi diğerleriyle karşılaştır - NLI modeliyle
86
  for (let i = 0; i < sentences.length; i++) {
87
  for (let j = i + 1; j < sentences.length; j++) {
88
  try {
89
- const sentence1 = sentences[i].trim();
90
- const sentence2 = sentences[j].trim();
91
-
92
- // Çok kısa cümleleri atla
93
- if (sentence1.length < 20 || sentence2.length < 20) continue;
94
 
95
  // Çok benzer başlangıçları atla
96
- if (sentence1.substring(0, 10) === sentence2.substring(0, 10)) continue;
 
 
 
 
97
 
98
- statusDiv.textContent = `Çelişki analizi yapılıyor... (${i + 1}/${sentences.length}) - ${Math.round(((i * sentences.length + j) / (sentences.length * sentences.length)) * 100)}%`;
99
 
100
- // NLI modeli ile çelişki testi - doğru format
101
- const result = await classifier(`${sentence1} [SEP] ${sentence2}`);
102
 
103
- console.log(`Analiz: "${sentence1.substring(0, 30)}..." vs "${sentence2.substring(0, 30)}..."`, result);
 
104
 
105
- // Eğer 'CONTRADICTION' yüksek skorsa, çelişki var demektir
106
- const contradictionResult = result.find(r => r.label === 'CONTRADICTION' || r.label === 'contradiction');
107
- const contradictionScore = contradictionResult?.score || 0;
108
 
109
- if (contradictionScore > 0.5) { // %50'den yüksek çelişki skoru
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  potentialContradictions.push({
111
  sentence1: sentence1,
112
  sentence2: sentence2,
113
- similarity: 1 - contradictionScore, // Tersine çevir (düşük benzerlik = yüksek çelişki)
114
  contradictionScore: contradictionScore
115
  });
116
  console.log(`✓ Çelişki bulundu! Skor: ${(contradictionScore * 100).toFixed(1)}%`);
117
  }
118
 
119
- // Kısa bekleme - her 3 karşılaştırmada bir
120
- if ((i * sentences.length + j) % 3 === 0) {
121
- await new Promise(resolve => setTimeout(resolve, 50));
122
  }
123
 
124
  } catch (error) {
125
  console.warn(`Cümle ${i}-${j} analiz edilirken hata:`, error);
 
 
 
 
 
 
 
 
 
126
  continue;
127
  }
128
  }
129
  }
130
 
131
- // Çok fazla çelişki varsa en güçlü olanları al
132
- if (potentialContradictions.length > 15) {
 
 
133
  potentialContradictions.sort((a, b) => b.contradictionScore - a.contradictionScore);
134
- const limitedContradictions = potentialContradictions.slice(0, 15);
135
- console.log(`${potentialContradictions.length} çelişki bulundu, en güçlü 15 tanesi gösteriliyor.`);
136
  statusDiv.style.display = 'none';
137
- renderResults(limitedContradictions, [], potentialContradictions.length);
138
  } else {
139
  statusDiv.style.display = 'none';
140
- renderResults(potentialContradictions, []);
141
  }
142
 
143
  } catch (error) {
 
144
  statusDiv.textContent = `Analiz sırasında hata: ${error.message}`;
145
  console.error('Detaylı hata:', error);
146
 
147
- // Kullanıcıya yardımcı öneriler
148
- if (error.message.includes('OrtRun') || error.message.includes('memory')) {
149
  statusDiv.innerHTML = `
150
- <strong>Bellek hatası oluştu.</strong><br>
151
- Öneriler:<br>
152
- Daha kısa bir metin deneyin<br>
153
- Sayfayı yenileyin ve tekrar deneyin<br>
154
- Diğer tarayıcı sekmelerini kapatın
 
 
 
 
 
 
 
 
 
 
155
  `;
156
  }
 
 
157
  }
158
  });
159
 
160
- function renderResults(results, allSimilarities, totalFound) {
161
  if (results.length === 0) {
162
- let message = '<p>Analiz tamamlandı. Belirlenen eşik değerinde potansiyel çelişki bulunamadı.</p>';
 
 
163
  message += `<div style="background-color: #f3f4f6; padding: 15px; border-radius: 5px; margin-top: 15px;">
164
- <h4>NLI (Natural Language Inference) Modeli</h4>
165
- <p>Bu model özellikle çelişki tespiti için tasarlanmıştır.</p>
166
- <p>%50'den yüksek çelişki skoru aranan çelişkiler için eşik değeridir.</p>
 
167
  </div>`;
 
168
  resultsDiv.innerHTML = message;
169
  return;
170
  }
171
 
172
- let headerText = `<h3>${results.length} adet potansiyel çelişki bulundu:</h3>`;
173
  if (totalFound && totalFound > results.length) {
174
- headerText = `<h3>Toplam ${totalFound} çelişki bulundu - En güçlü ${results.length} tanesi gösteriliyor:</h3>`;
175
  }
 
 
176
  resultsDiv.innerHTML = headerText;
177
 
178
- // Sonuçları çelişki skoruna göre sırala (en yüksek en üstte)
179
  results.sort((a, b) => b.contradictionScore - a.contradictionScore);
180
 
181
  results.forEach((item, index) => {
182
  const div = document.createElement('div');
183
  div.className = 'result-item';
184
 
185
- let severityColor = '#ef4444'; // kırmızı
186
  let severityText = 'Yüksek';
 
187
 
188
- if (item.contradictionScore > 0.8) {
189
- severityColor = '#dc2626'; // koyu kırmızı
190
  severityText = 'Çok Yüksek';
191
- }
192
- if (item.contradictionScore < 0.7) {
193
- severityColor = '#f59e0b'; // turuncu
194
- severityText = 'Orta';
 
 
 
 
 
195
  }
196
 
 
197
  div.innerHTML = `
198
- <p><strong>Çelişki #${index + 1} - Çelişki Skoru: <span style="color: ${severityColor}; font-weight: bold;">${(item.contradictionScore * 100).toFixed(1)}%</span> (${severityText} Seviye)</strong></p>
199
- <p><em>İfade 1:</em> ${item.sentence1.trim()}</p>
200
- <p><em>İfade 2:</em> ${item.sentence2.trim()}</p>
 
201
  `;
202
  resultsDiv.appendChild(div);
203
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
  </script>
206
  </body>
 
2
  <html lang="tr">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>Hugging Face API ile Çelişki Tespiti</title>
6
  <style>
7
  body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 2em; background-color: #f9fafb; color: #111827; }
8
+ .container { max-width: 900px; margin: 0 auto; background-color: white; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
9
  h1 { color: #374151; }
10
+ button { background-color: #3b82f6; color: white; border: none; padding: 10px 15px; border-radius: 5px; cursor: pointer; font-size: 16px; margin: 5px; }
11
  button:hover { background-color: #2563eb; }
12
+ button:disabled { background-color: #9ca3af; cursor: not-allowed; }
13
+ input[type="text"], input[type="password"] { width: 100%; padding: 10px; border: 1px solid #d1d5db; border-radius: 5px; font-size: 14px; margin: 5px 0; box-sizing: border-box; }
14
  #status { margin: 1em 0; padding: 1em; background-color: #eef2ff; border: 1px solid #c7d2fe; border-radius: 5px; display: none; }
15
  .result-item { border: 1px solid #e5e7eb; padding: 15px; margin-top: 15px; border-radius: 5px; }
16
  .result-item p { margin: 0.5em 0; }
17
  .similarity-score { font-weight: bold; color: #ef4444; }
18
+ .api-section { background-color: #f8fafc; padding: 20px; border-radius: 8px; margin-bottom: 20px; border: 2px solid #e2e8f0; }
19
+ .info-box { background-color: #dbeafe; padding: 15px; border-radius: 5px; margin: 10px 0; border-left: 4px solid #3b82f6; }
20
+ .model-select { margin: 10px 0; }
21
+ select { padding: 8px; border: 1px solid #d1d5db; border-radius: 5px; font-size: 14px; width: 100%; }
22
+ .progress-bar { background-color: #e5e7eb; height: 20px; border-radius: 10px; overflow: hidden; margin: 10px 0; }
23
+ .progress-bar-fill { background-color: #3b82f6; height: 100%; transition: width 0.3s ease; }
24
+ .warning-box { background-color: #fef3c7; padding: 15px; border-radius: 5px; margin: 10px 0; border-left: 4px solid #f59e0b; }
25
  </style>
26
  </head>
27
  <body>
28
  <div class="container">
29
+ <h1>🔍 Profesyonel Çelişki Tespiti</h1>
30
+ <p>Hugging Face API kullanarak güçlü dil modelleriyle çelişki analizi yapın.</p>
31
 
32
+ <div class="api-section">
33
+ <h3>🔑 API Yapılandırması</h3>
34
+ <div class="info-box">
35
+ <strong>Bilgi:</strong> Hugging Face API anahtarınızı <a href="https://huggingface.co/settings/tokens" target="_blank">buradan</a> alabilirsiniz.
36
+ Ücretsiz seviyede günde sınırlı sayıda istek atabilirsiniz.
37
+ </div>
38
+
39
+ <label for="api-key">Hugging Face API Anahtarı:</label>
40
+ <input type="password" id="api-key" placeholder="hf_xxxxxxxxxxxxxxxxxxxxxxxxx">
41
+
42
+ <div class="model-select">
43
+ <label for="model-select">Model Seçimi:</label>
44
+ <select id="model-select">
45
+ <option value="facebook/bart-large-mnli" selected>Facebook BART-Large-MNLI (Çelişki Tespiti - Önerilen)</option>
46
+ <option value="roberta-large-mnli">RoBERTa-Large-MNLI (Yüksek Performans)</option>
47
+ <option value="microsoft/deberta-v3-large-mnli">DeBERTa-v3-Large-MNLI (En İyi)</option>
48
+ <option value="MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli">DeBERTa-v3-base-MNLI (Hızlı)</option>
49
+ </select>
50
+ </div>
51
+ </div>
52
+
53
+ <div>
54
+ <input type="file" id="file-input" accept=".txt">
55
+ <button id="analyze-button">🔍 API ile Analiz Et</button>
56
+ </div>
57
 
58
  <div id="status"></div>
59
+ <div class="progress-bar" id="progress-container" style="display: none;">
60
+ <div class="progress-bar-fill" id="progress-bar"></div>
61
+ </div>
62
  <div id="results"></div>
63
  </div>
64
 
65
+ <script>
 
 
66
  const fileInput = document.getElementById('file-input');
67
  const analyzeButton = document.getElementById('analyze-button');
68
  const statusDiv = document.getElementById('status');
69
  const resultsDiv = document.getElementById('results');
70
+ const apiKeyInput = document.getElementById('api-key');
71
+ const modelSelect = document.getElementById('model-select');
72
+ const progressContainer = document.getElementById('progress-container');
73
+ const progressBar = document.getElementById('progress-bar');
74
 
75
+ let totalComparisons = 0;
76
+ let completedComparisons = 0;
 
 
 
 
 
 
 
77
 
78
+ // Progress bar güncelleme
79
+ function updateProgress() {
80
+ if (totalComparisons > 0) {
81
+ const percentage = (completedComparisons / totalComparisons) * 100;
82
+ progressBar.style.width = percentage + '%';
83
+ }
84
+ }
85
+
86
+ // Hugging Face NLI API ile çelişki tespiti
87
+ async function analyzeContradictionWithNLI(sentence1, sentence2, apiKey, modelName) {
88
+ const premise = sentence1;
89
+ const hypothesis = sentence2;
90
+
91
+ const response = await fetch(`https://api-inference.huggingface.co/models/${modelName}`, {
92
+ method: 'POST',
93
+ headers: {
94
+ 'Authorization': `Bearer ${apiKey}`,
95
+ 'Content-Type': 'application/json',
96
+ },
97
+ body: JSON.stringify({
98
+ inputs: {
99
+ premise: premise,
100
+ hypothesis: hypothesis
101
+ }
102
+ })
103
+ });
104
+
105
+ if (!response.ok) {
106
+ if (response.status === 503) {
107
+ // Model loading, retry after delay
108
+ await new Promise(resolve => setTimeout(resolve, 2000));
109
+ return await analyzeContradictionWithNLI(sentence1, sentence2, apiKey, modelName);
110
+ }
111
+ throw new Error(`API Error: ${response.status} - ${response.statusText}`);
112
+ }
113
+
114
+ const result = await response.json();
115
+
116
+ // API'den dönen format kontrol et
117
+ if (result.error) {
118
+ throw new Error(`API Error: ${result.error}`);
119
+ }
120
+
121
+ return result;
122
+ }
123
+
124
+ // Rate limiting için delay
125
+ async function delay(ms) {
126
+ return new Promise(resolve => setTimeout(resolve, ms));
127
+ }
128
+
129
+ statusDiv.style.display = 'block';
130
+ statusDiv.textContent = 'Sistem hazır. API anahtarınızı girin ve dosya seçip analiz edin.';
131
 
132
  analyzeButton.addEventListener('click', async () => {
133
+ const apiKey = apiKeyInput.value.trim();
134
+
135
+ if (!apiKey) {
136
+ alert("Lütfen Hugging Face API anahtarınızı girin.");
137
+ return;
138
+ }
139
+
140
  if (!fileInput.files || fileInput.files.length === 0) {
141
  alert("Lütfen bir dosya seçin.");
142
  return;
 
144
 
145
  const file = fileInput.files[0];
146
  const text = await file.text();
147
+ const selectedModel = modelSelect.value;
148
 
149
  statusDiv.style.display = 'block';
150
  statusDiv.textContent = 'Analiz başladı... Metin cümlelere ayrılıyor.';
151
  resultsDiv.innerHTML = '';
152
+ progressContainer.style.display = 'block';
153
+ progressBar.style.width = '0%';
154
+
155
+ analyzeButton.disabled = true;
156
 
157
  try {
158
+ // Metni cümlelere ayır
159
  let sentences = text.match(/[^.!?]+[.!?]+/g) || [];
160
  if (sentences.length < 2) {
161
  statusDiv.textContent = 'Analiz için en az 2 cümle bulunmalıdır.';
162
+ analyzeButton.disabled = false;
163
  return;
164
  }
165
 
166
+ // Kısa cümleleri filtrele ve temizle
167
+ sentences = sentences
168
+ .map(s => s.trim())
169
+ .filter(s => s.length > 20) // Minimum 20 karakter
170
+ .filter(s => s.split(' ').length > 3); // Minimum 3 kelime
171
+
172
+ // Çok fazla cümle varsa sınırla
173
+ const maxSentences = 50; // API rate limit için daha düşük
174
  if (sentences.length > maxSentences) {
175
  sentences = sentences.slice(0, maxSentences);
176
+ statusDiv.innerHTML = `<div class="warning-box">Performans ve API limitleri için analiz ${maxSentences} cümle ile sınırlandırıldı.</div>`;
177
  await new Promise(resolve => setTimeout(resolve, 2000));
178
  }
179
 
180
+ statusDiv.textContent = `Toplam ${sentences.length} cümle bulundu. ${selectedModel} modeli ile çelişki analizi başlıyor...`;
181
 
182
  const potentialContradictions = [];
183
+ totalComparisons = (sentences.length * (sentences.length - 1)) / 2;
184
+ completedComparisons = 0;
185
 
186
+ // Her cümleyi diğerleriyle karşılaştır
187
  for (let i = 0; i < sentences.length; i++) {
188
  for (let j = i + 1; j < sentences.length; j++) {
189
  try {
190
+ const sentence1 = sentences[i];
191
+ const sentence2 = sentences[j];
 
 
 
192
 
193
  // Çok benzer başlangıçları atla
194
+ if (sentence1.substring(0, 15) === sentence2.substring(0, 15)) {
195
+ completedComparisons++;
196
+ updateProgress();
197
+ continue;
198
+ }
199
 
200
+ statusDiv.textContent = `Çelişki analizi: ${completedComparisons + 1}/${totalComparisons} - Cümle ${i + 1} vs ${j + 1}`;
201
 
202
+ // API çağrısı
203
+ const result = await analyzeContradictionWithNLI(sentence1, sentence2, apiKey, selectedModel);
204
 
205
+ completedComparisons++;
206
+ updateProgress();
207
 
208
+ // Sonucu işle
209
+ let contradictionScore = 0;
 
210
 
211
+ if (Array.isArray(result)) {
212
+ // Eski format: array of objects
213
+ const contradictionResult = result.find(r =>
214
+ r.label === 'CONTRADICTION' ||
215
+ r.label === 'contradiction' ||
216
+ r.label === 'CONTRADICTORY'
217
+ );
218
+ contradictionScore = contradictionResult?.score || 0;
219
+ } else if (result.labels && result.scores) {
220
+ // Yeni format: object with labels and scores arrays
221
+ const contradictionIndex = result.labels.findIndex(label =>
222
+ label === 'CONTRADICTION' ||
223
+ label === 'contradiction' ||
224
+ label === 'CONTRADICTORY'
225
+ );
226
+ if (contradictionIndex !== -1) {
227
+ contradictionScore = result.scores[contradictionIndex];
228
+ }
229
+ }
230
+
231
+ console.log(`Analiz: "${sentence1.substring(0, 30)}..." vs "${sentence2.substring(0, 30)}..." - Çelişki: ${(contradictionScore * 100).toFixed(1)}%`);
232
+
233
+ // Çelişki eşiği
234
+ if (contradictionScore > 0.7) { // %70'den yüksek çelişki skoru
235
  potentialContradictions.push({
236
  sentence1: sentence1,
237
  sentence2: sentence2,
 
238
  contradictionScore: contradictionScore
239
  });
240
  console.log(`✓ Çelişki bulundu! Skor: ${(contradictionScore * 100).toFixed(1)}%`);
241
  }
242
 
243
+ // Rate limiting - her 5 istek arasında kısa bekleme
244
+ if (completedComparisons % 5 === 0) {
245
+ await delay(500);
246
  }
247
 
248
  } catch (error) {
249
  console.warn(`Cümle ${i}-${j} analiz edilirken hata:`, error);
250
+ completedComparisons++;
251
+ updateProgress();
252
+
253
+ if (error.message.includes('rate limit') || error.message.includes('429')) {
254
+ statusDiv.textContent = 'API rate limit aşıldı, 10 saniye bekleniyor...';
255
+ await delay(10000);
256
+ } else {
257
+ await delay(1000); // Genel hata durumunda kısa bekleme
258
+ }
259
  continue;
260
  }
261
  }
262
  }
263
 
264
+ progressContainer.style.display = 'none';
265
+
266
+ // Sonuçları göster
267
+ if (potentialContradictions.length > 20) {
268
  potentialContradictions.sort((a, b) => b.contradictionScore - a.contradictionScore);
269
+ const limitedContradictions = potentialContradictions.slice(0, 20);
 
270
  statusDiv.style.display = 'none';
271
+ renderResults(limitedContradictions, potentialContradictions.length, selectedModel);
272
  } else {
273
  statusDiv.style.display = 'none';
274
+ renderResults(potentialContradictions, null, selectedModel);
275
  }
276
 
277
  } catch (error) {
278
+ progressContainer.style.display = 'none';
279
  statusDiv.textContent = `Analiz sırasında hata: ${error.message}`;
280
  console.error('Detaylı hata:', error);
281
 
282
+ if (error.message.includes('401') || error.message.includes('Unauthorized')) {
 
283
  statusDiv.innerHTML = `
284
+ <div class="warning-box">
285
+ <strong>API Anahtarı Hatası:</strong><br>
286
+ API anahtarınızı kontrol edin<br>
287
+ Hugging Face hesabınızın aktif olduğundan emin olun<br>
288
+ API anahtarının "read" yetkisi olduğundan emin olun
289
+ </div>
290
+ `;
291
+ } else if (error.message.includes('rate limit') || error.message.includes('429')) {
292
+ statusDiv.innerHTML = `
293
+ <div class="warning-box">
294
+ <strong>Rate Limit Aşıldı:</strong><br>
295
+ • Çok fazla istek gönderildi<br>
296
+ • Birkaç dakika bekleyip tekrar deneyin<br>
297
+ • Daha kısa bir metin kullanmayı deneyin
298
+ </div>
299
  `;
300
  }
301
+ } finally {
302
+ analyzeButton.disabled = false;
303
  }
304
  });
305
 
306
+ function renderResults(results, totalFound, modelName) {
307
  if (results.length === 0) {
308
+ let message = '<div style="text-align: center; padding: 20px;">';
309
+ message += '<h3>🎉 Analiz Tamamlandı</h3>';
310
+ message += '<p>Belirlenen eşik değerinde (%70) potansiyel çelişki bulunamadı.</p>';
311
  message += `<div style="background-color: #f3f4f6; padding: 15px; border-radius: 5px; margin-top: 15px;">
312
+ <h4>${modelName} Modeli Sonucu</h4>
313
+ <p>Bu model özellikle çelişki tespiti için optimize edilmiştir.</p>
314
+ <p>%70'den yüksek çelişki skoru aranan eşik değeridir.</p>
315
+ <p>Sonuç: Metninizde güçlü çelişkiler tespit edilmemiştir.</p>
316
  </div>`;
317
+ message += '</div>';
318
  resultsDiv.innerHTML = message;
319
  return;
320
  }
321
 
322
+ let headerText = `<h3>🚨 ${results.length} adet potansiyel çelişki bulundu:</h3>`;
323
  if (totalFound && totalFound > results.length) {
324
+ headerText = `<h3>🚨 Toplam ${totalFound} çelişki bulundu - En güçlü ${results.length} tanesi gösteriliyor:</h3>`;
325
  }
326
+
327
+ headerText += `<p style="color: #6b7280; margin-bottom: 20px;">Model: <strong>${modelName}</strong> | Eşik: <strong>%70</strong></p>`;
328
  resultsDiv.innerHTML = headerText;
329
 
330
+ // Sonuçları çelişki skoruna göre sırala
331
  results.sort((a, b) => b.contradictionScore - a.contradictionScore);
332
 
333
  results.forEach((item, index) => {
334
  const div = document.createElement('div');
335
  div.className = 'result-item';
336
 
337
+ let severityColor = '#ef4444';
338
  let severityText = 'Yüksek';
339
+ let bgColor = '#fef2f2';
340
 
341
+ if (item.contradictionScore > 0.9) {
342
+ severityColor = '#dc2626';
343
  severityText = 'Çok Yüksek';
344
+ bgColor = '#fecaca';
345
+ } else if (item.contradictionScore > 0.8) {
346
+ severityColor = '#ef4444';
347
+ severityText = 'Yüksek';
348
+ bgColor = '#fef2f2';
349
+ } else if (item.contradictionScore > 0.7) {
350
+ severityColor = '#f59e0b';
351
+ severityText = 'Orta-Yüksek';
352
+ bgColor = '#fef3c7';
353
  }
354
 
355
+ div.style.backgroundColor = bgColor;
356
  div.innerHTML = `
357
+ <p><strong>Çelişki #${index + 1}</strong></p>
358
+ <p><strong>Çelişki Skoru: <span style="color: ${severityColor}; font-weight: bold;">${(item.contradictionScore * 100).toFixed(1)}%</span> (${severityText} Seviye)</strong></p>
359
+ <p><em>🔴 İfade 1:</em> "${item.sentence1.trim()}"</p>
360
+ <p><em>🔴 İfade 2:</em> "${item.sentence2.trim()}"</p>
361
  `;
362
  resultsDiv.appendChild(div);
363
  });
364
+
365
+ // Özet bilgi
366
+ const summaryDiv = document.createElement('div');
367
+ summaryDiv.style.cssText = 'background-color: #f3f4f6; padding: 20px; border-radius: 8px; margin-top: 20px; border-left: 4px solid #3b82f6;';
368
+ summaryDiv.innerHTML = `
369
+ <h4>📊 Analiz Özeti</h4>
370
+ <p><strong>Kullanılan Model:</strong> ${modelName}</p>
371
+ <p><strong>Toplam Çelişki:</strong> ${totalFound || results.length}</p>
372
+ <p><strong>Gösterilen:</strong> ${results.length}</p>
373
+ <p><strong>En Yüksek Skor:</strong> ${(results[0].contradictionScore * 100).toFixed(1)}%</p>
374
+ <p style="margin-top: 15px; color: #6b7280; font-size: 14px;">
375
+ <em>Not: Çelişki skoru %70'in üzerindeki cümle çiftleri potansiyel çelişki olarak değerlendirilmiştir.</em>
376
+ </p>
377
+ `;
378
+ resultsDiv.appendChild(summaryDiv);
379
  }
380
  </script>
381
  </body>