joermd commited on
Commit
52b6aeb
·
verified ·
1 Parent(s): 43df006

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +98 -74
index.html CHANGED
@@ -35,34 +35,44 @@
35
  تنسيقات النص والتظليل
36
  ================================= */
37
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
38
- .highlight-number {
39
- background-color: #FDE68A; /* أصفر */
 
40
  padding: 0 4px;
41
  border-radius: 3px;
42
  font-weight: bold;
43
  }
 
44
  .highlight-missing {
45
- background-color: #FECACA; /* أحمر للنصوص الناقصة */
46
  color: #B91C1C;
47
  padding: 0 4px;
48
  border-radius: 3px;
49
  font-style: italic;
50
  }
51
- .highlight-extra {
52
- background-color: #D1FAE5; /* أخضر للنصوص الزائدة */
53
- color: #065F46;
 
 
 
 
 
 
 
 
54
  padding: 0 4px;
55
  border-radius: 3px;
56
  font-weight: bold;
57
  }
58
  .highlight-meaning {
59
- background-color: #E0E7FF; /* أزرق فاتح لاختلاف المعنى */
60
  padding: 0 4px;
61
  border-radius: 3px;
62
  font-weight: bold;
63
  }
64
  .highlight-doubt {
65
- background-color: #DBEAFE; /* أزرق لعناصر الشك */
66
  color: #1E3A8A;
67
  padding: 0 4px;
68
  border-radius: 3px;
@@ -101,7 +111,7 @@
101
  .icon { margin-right: 0.5rem; }
102
 
103
  /* ================================
104
- تصميم شاشة الأخطاء والنتائج
105
  ================================= */
106
  #errorsList div {
107
  margin-bottom: 0.5rem;
@@ -117,7 +127,7 @@
117
  <i class="fas fa-chart-line icon"></i> نظام المقارنة والتحليل المتقدم
118
  </h1>
119
  <p class="text-xl opacity-90">
120
- <i class="fas fa-info-circle icon"></i> استخراج كافة المشاكل مع التركيز على النصوص المفقودة
121
  </p>
122
  </div>
123
  </header>
@@ -215,13 +225,13 @@
215
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
216
  <div>
217
  <h4 class="text-lg font-bold text-gray-700 mb-3">
218
- <i class="fas fa-file-alt icon text-indigo-600"></i> النص المصدر (مع التعليم)
219
  </h4>
220
  <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-6 min-h-[200px] border-2 border-indigo-100 text-comparison"></div>
221
  </div>
222
  <div>
223
  <h4 class="text-lg font-bold text-gray-700 mb-3">
224
- <i class="fas fa-file-alt icon text-pink-600"></i> النص الهدف (مع التعليم)
225
  </h4>
226
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
227
  </div>
@@ -242,23 +252,19 @@
242
  جافا سكريبت: الوظائف والتحليل
243
  ================================= -->
244
  <script>
245
- // إعدادات الـ API والبرومبت
246
  const API_URL = 'https://api.deepseek.com/chat/completions';
247
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
248
- const ANALYSIS_PROMPT = `أنت خبير لغوي وتقني متخصص في مراجعة الترجمة التقنية وتحليل النصوص بدقة عالية. مهمتك مقارنة النص المصدر والنص الهدف واستخراج كافة المشاكل مع التركيز بشكل خاص على النصوص المفقودة.
249
- تعليمات:
250
- 1. قم بتحليل النص إلى فقرات منفصلة مع التأكد من انتهاء كل فقرة بنقطة.
251
- 2. لا تقم بتعديل العلامات التالية:
252
- - الأرقام والتواريخ محاطة بـ < و >.
253
- - النصوص المفقودة محاطة بـ __ و __.
254
- - النصوص الزائدة محاطة بـ <<EXTRA>> و <<\/EXTRA>>.
255
- - اختلافات المعنى محاطة بـ [MEANING] و [/MEANING].
256
- - علامات الشك أو الأخطاء البسيطة محاط�� بـ [DOUBT] و [/DOUBT].
257
- 3. قم باستخراج كافة المشاكل، وعلى رأسها النصوص المفقودة، مع تقديم شرح تفصيلي مدعوم بأيقونات توضيحية لكل فئة.
258
-
259
  النص المصدر:
260
  {source}
261
-
262
  النص الهدف:
263
  {target}`;
264
 
@@ -284,41 +290,50 @@
284
  return text.substring(0, index).split("\n").length;
285
  }
286
 
287
- // دوال التظليل (Highlighting) لكل نوع من المشاكل
288
  function applyHighlights(originalText, analysisOutput) {
289
  let highlightedText = originalText;
290
  let match;
291
- // اختلافات الأرقام/التواريخ
292
- const numberRegex = /<([^<>]+)>/g;
293
- while ((match = numberRegex.exec(analysisOutput)) !== null) {
294
  const phrase = match[1].trim();
295
  if (phrase) {
296
- const replacement = `<span class="highlight-number">${phrase}</span>`;
297
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
298
  highlightedText = highlightedText.replace(phraseRegex, replacement);
299
  }
300
  }
301
- // النصوص المفقودة (يتم استخراجها بأهمية خاصة)
302
- const missingRegex = /__(.*?)__/g;
303
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
304
  const phrase = match[1].trim();
305
  if (phrase) {
306
- const replacement = `<span class="highlight-missing">__${phrase}__</span>`;
307
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
308
  highlightedText = highlightedText.replace(phraseRegex, replacement);
309
  }
310
  }
311
- // النصوص الزائدة
312
- const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
313
- while ((match = extraRegex.exec(analysisOutput)) !== null) {
314
  const phrase = match[1].trim();
315
  if (phrase) {
316
- const replacement = `<span class="highlight-extra">${phrase}</span>`;
 
 
 
 
 
 
 
 
 
 
317
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
318
  highlightedText = highlightedText.replace(phraseRegex, replacement);
319
  }
320
  }
321
- // اختلافات المعنى
322
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
323
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
324
  const phrase = match[1].trim();
@@ -328,7 +343,6 @@
328
  highlightedText = highlightedText.replace(phraseRegex, replacement);
329
  }
330
  }
331
- // علامات الشك أو الأخطاء البسيطة
332
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
333
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
334
  const phrase = match[1].trim();
@@ -341,62 +355,71 @@
341
  return highlightedText;
342
  }
343
 
344
- // دالة توليد شرح تفصيلي للاختلافات مع أيقونات توضيحية لكل مشكلة
345
  function generateExplanation(sourceText, analysisOutput) {
346
  let steps = [];
347
  let match;
 
348
  const iconMissing = `<i class="fas fa-exclamation-triangle text-red-500 mr-1"></i>`;
 
349
  const iconNumber = `<i class="fas fa-hashtag text-yellow-600 mr-1"></i>`;
350
- const iconExtra = `<i class="fas fa-plus-circle text-green-600 mr-1"></i>`;
351
  const iconMeaning = `<i class="fas fa-info-circle text-blue-600 mr-1"></i>`;
352
  const iconDoubt = `<i class="fas fa-question-circle text-indigo-600 mr-1"></i>`;
353
 
354
- // استخراج النصوص المفقودة (تظهر كأولوية)
355
- const missingRegex = /__(.*?)__/g;
356
- while ((match = missingRegex.exec(analysisOutput)) !== null) {
357
  const phrase = match[1].trim();
358
- if (phrase) {
359
  const lineNum = getLineNumber(sourceText, phrase);
360
- steps.push(`<li>${iconMissing} <strong>نص مفقود</strong> في السطر ${lineNum}: <span class="highlight-missing">__${phrase}__</span> غير موجود في النص الهدف.</li>`);
361
  }
362
  }
363
- // استخراج اختلافات الأرقام/التواريخ
364
- const numberRegex = /<([^<>]+)>/g;
365
- while ((match = numberRegex.exec(analysisOutput)) !== null) {
366
  const phrase = match[1].trim();
367
- if (phrase) {
368
  const lineNum = getLineNumber(sourceText, phrase);
369
- steps.push(`<li>${iconNumber} في السطر ${lineNum}: الرقم/التاريخ <span class="highlight-number">${phrase}</span> لا يتطابق بين المصدر والهدف.</li>`);
 
 
 
 
 
 
 
 
 
370
  }
371
  }
372
- // استخراج النصوص الزائدة
373
- const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
374
- while ((match = extraRegex.exec(analysisOutput)) !== null) {
375
  const phrase = match[1].trim();
376
  if (phrase) {
377
  const lineNum = getLineNumber(sourceText, phrase);
378
- steps.push(`<li>${iconExtra} في السطر ${lineNum}: النص الزائد <span class="highlight-extra">${phrase}</span> موجود بشكل غير متوقع في النص الهدف.</li>`);
379
  }
380
  }
381
- // استخراج اختلافات المعنى
382
- const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
383
- while ((match = meaningRegex.exec(analysisOutput)) !== null) {
384
  const phrase = match[1].trim();
385
  if (phrase) {
386
  const lineNum = getLineNumber(sourceText, phrase);
387
  steps.push(`<li>${iconMeaning} في السطر ${lineNum}: اختلاف في المعنى مع التعبير <span class="highlight-meaning">${phrase}</span>.</li>`);
388
  }
389
  }
390
- // استخراج علامات الشك أو الأخطاء البسيطة
391
- const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
392
- while ((match = doubtRegex.exec(analysisOutput)) !== null) {
393
  const phrase = match[1].trim();
394
  if (phrase) {
395
  const lineNum = getLineNumber(sourceText, phrase);
396
  steps.push(`<li>${iconDoubt} في السطر ${lineNum}: علامة شك أو خطأ بسيط <span class="highlight-doubt">${phrase}</span> تحتاج مراجعة.</li>`);
397
  }
398
  }
399
-
400
  if (steps.length === 0) {
401
  return `<p class="text-green-700"><i class="fas fa-check-circle mr-2"></i> لا توجد اختلافات ملحوظة بين النصين.</p>`;
402
  }
@@ -525,7 +548,6 @@
525
  max_tokens: 2048,
526
  stream: false
527
  };
528
-
529
  const response = await fetch(API_URL, {
530
  method: 'POST',
531
  headers: {
@@ -541,7 +563,7 @@
541
  const analysisOutput = data.choices[0].message.content.trim();
542
  progressDiv.remove();
543
 
544
- // في حال كانت النصوص متطابقة تماماً
545
  if (analysisOutput.includes('[MATCH]')) {
546
  const checkDiv = document.createElement('div');
547
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
@@ -551,29 +573,31 @@
551
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
552
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا توجد فروقات يجب الإشارة إليها.</p>`;
553
  } else {
554
- // تطبيق التظليل على النصوص المُدخلة
555
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
556
- const targetHighlighted = applyHighlights(targetText, analysisOutput);
557
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
558
- document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
559
- // توليد شرح تفصيلي لكل مشكلة تم استخراجها
 
560
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
561
  document.getElementById('explanationText').innerHTML = explanationHTML;
562
 
563
- // عرض ملخص للإختلافات بشكل عام
564
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
565
- const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
566
- const extraDiffCount = (analysisOutput.match(/<<EXTRA>>(.*?)<<\/EXTRA>>/g) || []).length;
 
567
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
568
  const doubtDiffCount = (analysisOutput.match(/\[DOUBT\](.*?)\[\/DOUBT\]/g) || []).length;
569
 
570
- if (numDiffCount || missingDiffCount || extraDiffCount || meaningDiffCount || doubtDiffCount) {
571
  const summaryDiv = document.createElement('div');
572
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
573
  let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc ml-4 space-y-1">';
574
- if (missingDiffCount) summaryText += `<li>النصوص المفقودة: ${missingDiffCount}</li>`;
 
 
575
  if (numDiffCount) summaryText += `<li>اختلاف في الأرقام/التواريخ: ${numDiffCount}</li>`;
576
- if (extraDiffCount) summaryText += `<li>النصوص الزائدة: ${extraDiffCount}</li>`;
577
  if (meaningDiffCount) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
578
  if (doubtDiffCount) summaryText += `<li>علامات الشك: ${doubtDiffCount}</li>`;
579
  summaryText += '</ul>';
 
35
  تنسيقات النص والتظليل
36
  ================================= */
37
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
38
+ /* اختلافات بسيطة (نوع MINOR) */
39
+ .highlight-minor {
40
+ background-color: #FFF9C4; /* أصفر فاتح */
41
  padding: 0 4px;
42
  border-radius: 3px;
43
  font-weight: bold;
44
  }
45
+ /* جمل مفقودة بالكامل (نوع MISSING) */
46
  .highlight-missing {
47
+ background-color: #FECACA; /* أحمر فاتح */
48
  color: #B91C1C;
49
  padding: 0 4px;
50
  border-radius: 3px;
51
  font-style: italic;
52
  }
53
+ /* جمل ناقصة (نوع PARTIAL) */
54
+ .highlight-partial {
55
+ background-color: #FFCDD2; /* أحمر باهت */
56
+ color: #B91C1C;
57
+ padding: 0 4px;
58
+ border-radius: 3px;
59
+ font-weight: bold;
60
+ }
61
+ /* تظليل الاختلافات الأخرى (أرقام، تواريخ، اختلاف معاني، علامات شك) */
62
+ .highlight-number {
63
+ background-color: #FDE68A; /* أصفر */
64
  padding: 0 4px;
65
  border-radius: 3px;
66
  font-weight: bold;
67
  }
68
  .highlight-meaning {
69
+ background-color: #E0E7FF;
70
  padding: 0 4px;
71
  border-radius: 3px;
72
  font-weight: bold;
73
  }
74
  .highlight-doubt {
75
+ background-color: #DBEAFE; /* أزرق */
76
  color: #1E3A8A;
77
  padding: 0 4px;
78
  border-radius: 3px;
 
111
  .icon { margin-right: 0.5rem; }
112
 
113
  /* ================================
114
+ شاشة الأخطاء والنتائج
115
  ================================= */
116
  #errorsList div {
117
  margin-bottom: 0.5rem;
 
127
  <i class="fas fa-chart-line icon"></i> نظام المقارنة والتحليل المتقدم
128
  </h1>
129
  <p class="text-xl opacity-90">
130
+ <i class="fas fa-info-circle icon"></i> استخراج كافة المشاكل مع التركيز على النصوص المفقودة في المصدر
131
  </p>
132
  </div>
133
  </header>
 
225
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
226
  <div>
227
  <h4 class="text-lg font-bold text-gray-700 mb-3">
228
+ <i class="fas fa-file-alt icon text-indigo-600"></i> النص المصدر (مع التظليل)
229
  </h4>
230
  <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-6 min-h-[200px] border-2 border-indigo-100 text-comparison"></div>
231
  </div>
232
  <div>
233
  <h4 class="text-lg font-bold text-gray-700 mb-3">
234
+ <i class="fas fa-file-alt icon text-pink-600"></i> النص الهدف (بدون تظليل)
235
  </h4>
236
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
237
  </div>
 
252
  جافا سكريبت: الوظائف والتحليل
253
  ================================= -->
254
  <script>
255
+ // إعدادات الـ API والبرومبت مع تعليمات استخدام العلامات الجديدة
256
  const API_URL = 'https://api.deepseek.com/chat/completions';
257
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
258
+ const ANALYSIS_PROMPT = `أنت خبير لغوي وتقني متخصص في مراجعة الترجمة التقنية وتحليل النصوص بدقة عالية.
259
+ مهمتك مقارنة النص المصدر والنص الهدف واستخراج كافة المشاكل وفقاً للأنواع التالية:
260
+ 1. إذا كانت الجملة موجودة في النصين ولكن بها اختلاف بسيط (مثال: اختلاف كلمة أو تاريخ أو معنى بسيط) فاستخدم العلامة [MINOR] ... [/MINOR].
261
+ 2. إذا كانت الجملة مختلفة تماماً (أي بها 3 اختلافات أو أكثر) فتعتبر مفقودة في النص الهدف، فاستخدم العلامة [MISSING] ... [/MISSING].
262
+ 3. إذا كانت الجملة موجودة في النص المصدر ولكنها ناقصة أو بها كلمات مفقودة في النص الهدف، فاستخدم العلامة [PARTIAL] ... [/PARTIAL].
263
+ يُرجى إظهار العلامات في النص المصدر لتبيان مكان الخطأ.
264
+
 
 
 
 
265
  النص المصدر:
266
  {source}
267
+
268
  النص الهدف:
269
  {target}`;
270
 
 
290
  return text.substring(0, index).split("\n").length;
291
  }
292
 
293
+ // دالة تطبيق التظليل على النص المصدر باستخدام العلامات الجديدة
294
  function applyHighlights(originalText, analysisOutput) {
295
  let highlightedText = originalText;
296
  let match;
297
+ // اختلاف بسيط [MINOR]
298
+ const minorRegex = /\[MINOR\](.*?)\[\/MINOR\]/g;
299
+ while ((match = minorRegex.exec(analysisOutput)) !== null) {
300
  const phrase = match[1].trim();
301
  if (phrase) {
302
+ const replacement = `<span class="highlight-minor">${phrase}</span>`;
303
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
304
  highlightedText = highlightedText.replace(phraseRegex, replacement);
305
  }
306
  }
307
+ // جملة مفقودة [MISSING]
308
+ const missingRegex = /\[MISSING\](.*?)\[\/MISSING\]/g;
309
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
310
  const phrase = match[1].trim();
311
  if (phrase) {
312
+ const replacement = `<span class="highlight-missing">${phrase}</span>`;
313
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
314
  highlightedText = highlightedText.replace(phraseRegex, replacement);
315
  }
316
  }
317
+ // جملة ناقصة [PARTIAL]
318
+ const partialRegex = /\[PARTIAL\](.*?)\[\/PARTIAL\]/g;
319
+ while ((match = partialRegex.exec(analysisOutput)) !== null) {
320
  const phrase = match[1].trim();
321
  if (phrase) {
322
+ const replacement = `<span class="highlight-partial">${phrase}</span>`;
323
+ const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
324
+ highlightedText = highlightedText.replace(phraseRegex, replacement);
325
+ }
326
+ }
327
+ // يمكن الإبقاء على التظليل السابق للأرقام والتواريخ واختلاف المعنى وعلامات الشك إن وجدت
328
+ const numberRegex = /<([^<>]+)>/g;
329
+ while ((match = numberRegex.exec(analysisOutput)) !== null) {
330
+ const phrase = match[1].trim();
331
+ if (phrase) {
332
+ const replacement = `<span class="highlight-number">${phrase}</span>`;
333
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
334
  highlightedText = highlightedText.replace(phraseRegex, replacement);
335
  }
336
  }
 
337
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
338
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
339
  const phrase = match[1].trim();
 
343
  highlightedText = highlightedText.replace(phraseRegex, replacement);
344
  }
345
  }
 
346
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
347
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
348
  const phrase = match[1].trim();
 
355
  return highlightedText;
356
  }
357
 
358
+ // دالة توليد شرح تفصيلي للاختلافات باستخدام العلامات الجديدة مع أيقونات توضيحية
359
  function generateExplanation(sourceText, analysisOutput) {
360
  let steps = [];
361
  let match;
362
+ const iconMinor = `<i class="fas fa-edit text-orange-500 mr-1"></i>`;
363
  const iconMissing = `<i class="fas fa-exclamation-triangle text-red-500 mr-1"></i>`;
364
+ const iconPartial = `<i class="fas fa-minus-circle text-red-500 mr-1"></i>`;
365
  const iconNumber = `<i class="fas fa-hashtag text-yellow-600 mr-1"></i>`;
 
366
  const iconMeaning = `<i class="fas fa-info-circle text-blue-600 mr-1"></i>`;
367
  const iconDoubt = `<i class="fas fa-question-circle text-indigo-600 mr-1"></i>`;
368
 
369
+ // استخراج اختلاف بسيط [MINOR]
370
+ const minorRegex2 = /\[MINOR\](.*?)\[\/MINOR\]/g;
371
+ while ((match = minorRegex2.exec(analysisOutput)) !== null) {
372
  const phrase = match[1].trim();
373
+ if(phrase) {
374
  const lineNum = getLineNumber(sourceText, phrase);
375
+ steps.push(`<li>${iconMinor} في السطر ${lineNum}: اختلاف بسيط في الجملة <span class="highlight-minor">${phrase}</span>.</li>`);
376
  }
377
  }
378
+ // استخراج جملة مفقودة [MISSING]
379
+ const missingRegex2 = /\[MISSING\](.*?)\[\/MISSING\]/g;
380
+ while ((match = missingRegex2.exec(analysisOutput)) !== null) {
381
  const phrase = match[1].trim();
382
+ if(phrase) {
383
  const lineNum = getLineNumber(sourceText, phrase);
384
+ steps.push(`<li>${iconMissing} في السطر ${lineNum}: جملة مفقودة <span class="highlight-missing">${phrase}</span> غير موجودة في النص الهدف.</li>`);
385
+ }
386
+ }
387
+ // استخراج جملة ناقصة [PARTIAL]
388
+ const partialRegex2 = /\[PARTIAL\](.*?)\[\/PARTIAL\]/g;
389
+ while ((match = partialRegex2.exec(analysisOutput)) !== null) {
390
+ const phrase = match[1].trim();
391
+ if(phrase) {
392
+ const lineNum = getLineNumber(sourceText, phrase);
393
+ steps.push(`<li>${iconPartial} في السطر ${lineNum}: جملة ناقصة أو بها كلمات مفقودة <span class="highlight-partial">${phrase}</span> في النص الهدف.</li>`);
394
  }
395
  }
396
+ // استخراج اختلافات الأرقام/التواريخ إن وجدت
397
+ const numberRegex2 = /<([^<>]+)>/g;
398
+ while ((match = numberRegex2.exec(analysisOutput)) !== null) {
399
  const phrase = match[1].trim();
400
  if (phrase) {
401
  const lineNum = getLineNumber(sourceText, phrase);
402
+ steps.push(`<li>${iconNumber} في السطر ${lineNum}: الرقم/التاريخ <span class="highlight-number">${phrase}</span> لا يتطابق بين المصدر والهدف.</li>`);
403
  }
404
  }
405
+ // استخراج اختلافات المعنى إن وجدت
406
+ const meaningRegex2 = /\[MEANING\](.*?)\[\/MEANING\]/g;
407
+ while ((match = meaningRegex2.exec(analysisOutput)) !== null) {
408
  const phrase = match[1].trim();
409
  if (phrase) {
410
  const lineNum = getLineNumber(sourceText, phrase);
411
  steps.push(`<li>${iconMeaning} في السطر ${lineNum}: اختلاف في المعنى مع التعبير <span class="highlight-meaning">${phrase}</span>.</li>`);
412
  }
413
  }
414
+ // استخراج علامات الشك أو الأخطاء البسيطة إن وجدت
415
+ const doubtRegex2 = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
416
+ while ((match = doubtRegex2.exec(analysisOutput)) !== null) {
417
  const phrase = match[1].trim();
418
  if (phrase) {
419
  const lineNum = getLineNumber(sourceText, phrase);
420
  steps.push(`<li>${iconDoubt} في السطر ${lineNum}: علامة شك أو خطأ بسيط <span class="highlight-doubt">${phrase}</span> تحتاج مراجعة.</li>`);
421
  }
422
  }
 
423
  if (steps.length === 0) {
424
  return `<p class="text-green-700"><i class="fas fa-check-circle mr-2"></i> لا توجد اختلافات ملحوظة بين النصين.</p>`;
425
  }
 
548
  max_tokens: 2048,
549
  stream: false
550
  };
 
551
  const response = await fetch(API_URL, {
552
  method: 'POST',
553
  headers: {
 
563
  const analysisOutput = data.choices[0].message.content.trim();
564
  progressDiv.remove();
565
 
566
+ // إذا كانت النصوص متطابقة تماماً
567
  if (analysisOutput.includes('[MATCH]')) {
568
  const checkDiv = document.createElement('div');
569
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
 
573
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
574
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا توجد فروقات يجب الإشارة إليها.</p>`;
575
  } else {
576
+ // تطبيق التظليل على النص المصدر فقط
577
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
 
578
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
579
+ // عرض النص الهدف بدون تظليل
580
+ document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
581
+ // توليد شرح تفصيلي لكل مشكلة تم استخراجها باستخدام العلامات الجديدة
582
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
583
  document.getElementById('explanationText').innerHTML = explanationHTML;
584
 
585
+ // عرض ملخص للإختلافات بشكل عام إن وُجدت
586
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
587
+ const minorDiffCount = (analysisOutput.match(/\[MINOR\](.*?)\[\/MINOR\]/g) || []).length;
588
+ const missingDiffCount = (analysisOutput.match(/\[MISSING\](.*?)\[\/MISSING\]/g) || []).length;
589
+ const partialDiffCount = (analysisOutput.match(/\[PARTIAL\](.*?)\[\/PARTIAL\]/g) || []).length;
590
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
591
  const doubtDiffCount = (analysisOutput.match(/\[DOUBT\](.*?)\[\/DOUBT\]/g) || []).length;
592
 
593
+ if (minorDiffCount || missingDiffCount || partialDiffCount || numDiffCount || meaningDiffCount || doubtDiffCount) {
594
  const summaryDiv = document.createElement('div');
595
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
596
  let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc ml-4 space-y-1">';
597
+ if (minorDiffCount) summaryText += `<li>اختلاف بسيط: ${minorDiffCount}</li>`;
598
+ if (missingDiffCount) summaryText += `<li>جمل مفقودة: ${missingDiffCount}</li>`;
599
+ if (partialDiffCount) summaryText += `<li>جمل ناقصة: ${partialDiffCount}</li>`;
600
  if (numDiffCount) summaryText += `<li>اختلاف في الأرقام/التواريخ: ${numDiffCount}</li>`;
 
601
  if (meaningDiffCount) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
602
  if (doubtDiffCount) summaryText += `<li>علامات الشك: ${doubtDiffCount}</li>`;
603
  summaryText += '</ul>';