joermd commited on
Commit
b5ef197
·
verified ·
1 Parent(s): babba69

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +130 -179
index.html CHANGED
@@ -3,14 +3,14 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>نظام المقارنة والترجمة الخاص بشركة موندو لينجوا</title>
7
  <!-- استيراد مكتبات Tailwind وFont Awesome وMammoth -->
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script>
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
11
  <style>
12
  /* ================================
13
- تنسيقات الحركات والتأثيرات
14
  ================================= */
15
  @keyframes gradient {
16
  0% { background-position: 0% 50%; }
@@ -30,9 +30,9 @@
30
  70% { box-shadow: 0 0 0 10px rgba(156,39,176,0); }
31
  100% { box-shadow: 0 0 0 0 rgba(156,39,176,0); }
32
  }
33
-
34
  /* ================================
35
- تنسيقات النصوص والتحديد
36
  ================================= */
37
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
38
  .highlight-number {
@@ -62,78 +62,81 @@
62
  font-weight: bold;
63
  }
64
  .highlight-doubt {
65
- background-color: #DBEAFE; /* أزرق لعلامات الشك أو الأخطاء البسيطة */
66
  color: #1E3A8A;
67
  padding: 0 4px;
68
  border-radius: 3px;
69
  font-weight: bold;
70
  }
71
-
72
  /* ================================
73
- تنسيق عرض السطور في المعاينة
74
  ================================= */
75
- .split-view {
76
- display: grid;
77
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
78
- gap: 1rem;
79
- }
80
  .line-item {
81
- display: flex;
82
- align-items: flex-start;
83
- margin-bottom: 0.5rem;
84
  }
85
  .line-number {
86
- width: 30px;
87
  font-weight: bold;
88
  color: #4B5563;
89
- flex-shrink: 0;
90
  }
91
- .line-text { flex: 1; }
92
-
93
  /* ================================
94
- تحسين تنسيق البطاقات والعناصر
95
  ================================= */
96
- .card-hover {
97
- transition: all 0.3s ease;
 
 
 
 
98
  }
99
  .card-hover:hover {
100
- box-shadow: 0 10px 25px -5px rgba(156,39,176,0.1), 0 10px 10px -5px rgba(156,39,176,0.04);
101
- transform: translateY(-2px);
102
  }
 
103
  </style>
104
  </head>
105
  <body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
106
  <div class="min-h-screen pb-12">
107
- <!-- ============ رأس الصفحة ============ -->
108
  <header class="bg-gradient-to-r from-indigo-700 via-purple-700 to-pink-700 animate-gradient text-white py-10 mb-10 shadow-xl">
109
- <div class="max-w-6xl mx-auto px-4">
110
- <h1 class="text-5xl font-bold text-center mb-4 animate-scale">نظام شركة موندو لينجوا</h1>
111
- <p class="text-center text-xl text-blue-100 opacity-90">مقارنة وتحليل النصوص المصدر مرجع أساسي</p>
 
 
 
 
112
  </div>
113
  </header>
114
 
115
- <!-- ============ المحتوى الرئيسي ============ -->
116
- <main class="max-w-6xl mx-auto px-4">
117
  <!-- قسم رفع الملفات -->
118
- <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
119
- <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
120
- <i class="fas fa-file-upload text-indigo-600 ml-2"></i> تحميل الملفات
121
  </h2>
122
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
123
- <!-- ملف السورس -->
124
- <div class="group border-2 border-dashed border-indigo-300 rounded-xl p-8 text-center hover:border-indigo-500 transition-colors duration-300 bg-indigo-50 hover:bg-indigo-100">
125
  <label class="cursor-pointer block">
126
  <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
127
- <i class="fas fa-file-upload text-5xl text-indigo-500 mb-4"></i>
128
- <span class="text-lg text-indigo-600 group-hover:text-indigo-700">ملف السورس</span>
129
  </label>
130
  </div>
131
- <!-- ملف التارجت -->
132
- <div class="group border-2 border-dashed border-pink-300 rounded-xl p-8 text-center hover:border-pink-500 transition-colors duration-300 bg-pink-50 hover:bg-pink-100">
133
  <label class="cursor-pointer block">
134
  <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
135
- <i class="fas fa-file-download text-5xl text-pink-500 mb-4"></i>
136
- <span class="text-lg text-pink-600 group-hover:text-pink-700">ملف التارجت</span>
137
  </label>
138
  </div>
139
  </div>
@@ -146,19 +149,19 @@
146
  </div>
147
 
148
  <!-- قسم إدخال النصوص يدويًا -->
149
- <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
150
  <div class="space-y-6">
151
  <!-- النص المصدر -->
152
  <div class="group">
153
- <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
154
- <i class="fas fa-language text-indigo-600 ml-2"></i> النص المصدر
155
  </label>
156
  <textarea id="sourceText" dir="rtl" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
157
  </div>
158
  <!-- النص الهدف -->
159
  <div class="group">
160
- <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
161
- <i class="fas fa-language text-pink-600 ml-2"></i> النص الهدف
162
  </label>
163
  <textarea id="targetText" dir="ltr" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-pink-200 focus:border-pink-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
164
  </div>
@@ -166,13 +169,13 @@
166
  </div>
167
 
168
  <!-- قسم المصادر الإضافية -->
169
- <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
170
- <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
171
- <i class="fas fa-book-open text-green-600 ml-2"></i> مصادر إضافية
172
  </h2>
173
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
174
  <!-- رفع ملف المصادر الإضافية -->
175
- <div class="group border-2 border-dashed border-green-300 rounded-xl p-8 text-center hover:border-green-500 transition-colors duration-300 bg-green-50 hover:bg-green-100">
176
  <label class="cursor-pointer block">
177
  <input type="file" id="sourceExtraFile" accept=".docx,.pdf" class="hidden">
178
  <i class="fas fa-upload text-5xl text-green-500 mb-4"></i>
@@ -181,49 +184,47 @@
181
  </div>
182
  <!-- إدخال المصادر يدويًا -->
183
  <div class="group">
184
- <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
185
- <i class="fas fa-edit text-green-600 ml-2"></i> إدخال المصادر يدويًا
186
  </label>
187
  <textarea id="sourceExtraText" dir="rtl" class="w-full px-6 py-4 border-2 border-green-200 rounded-xl focus:ring-green-200 focus:border-green-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب المصادر هنا..."></textarea>
188
  </div>
189
  </div>
190
  </div>
191
 
192
- <!-- زر التحليل -->
193
- <button id="submitBtn" class="w-full bg-gradient-to-r from-indigo-600 to-pink-600 hover:from-indigo-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-xl transition-all transform hover:scale-105 focus:ring-indigo-200 text-xl shadow-lg hover:shadow-xl mb-8 pulse-animation">
194
  <div class="flex items-center justify-center">
195
- <i class="fas fa-sync-alt ml-2"></i> تحليل ومراجعة النصوص
196
  </div>
197
  </button>
198
 
199
- <!-- شاشة عرض نتائج التحليل -->
200
- <div id="resultSection" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
201
- <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
202
- <i class="fas fa-search text-green-600 ml-2"></i> نتائج التحليل والمقارنة
203
  </h2>
204
  <div id="errorsList" class="space-y-3 mb-6"></div>
205
- <div class="result-section split-view">
206
- <!-- عرض النص المصدر بعد التحديد مع ترقيم السطور -->
207
  <div>
208
- <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
209
- <i class="fas fa-file-alt text-indigo-600 ml-2"></i> النص المصدر (مع التعليم)
210
  </h4>
211
  <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-6 min-h-[200px] border-2 border-indigo-100 text-comparison"></div>
212
  </div>
213
- <!-- عرض النص الهدف بعد التحديد مع ترقيم السطور -->
214
  <div>
215
- <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
216
- <i class="fas fa-file-alt text-pink-600 ml-2"></i> النص الهدف (مع التعليم)
217
  </h4>
218
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
219
  </div>
220
  </div>
221
  </div>
222
 
223
- <!-- صندوق عرض الشرح التفصيلي للنتائج -->
224
- <div id="explanationBox" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
225
- <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
226
- <i class="fas fa-info-circle text-green-600 ml-2"></i> شرح الاختلافات
227
  </h2>
228
  <div id="explanationText" class="text-lg text-gray-700"></div>
229
  </div>
@@ -231,78 +232,53 @@
231
  </div>
232
 
233
  <!-- ================================
234
- جافا سكريبت: الوظائف والمعالجة
235
  ================================= -->
236
  <script>
237
- // إعدادات API
238
  const API_URL = 'https://api.deepseek.com/chat/completions';
239
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
240
-
241
- /*
242
- البرومبت الجديد:
243
- - تحليل النص كفقرات مع التأكد من انتهاء كل فقرة بنقطة.
244
- - التحقق من النصوص الناقصة، النصوص الزائدة، اختلافات المعنى،
245
- اختلافات الأرقام/التواريخ وعلامات الشك أو الأخطاء البسيطة.
246
- - تُحاط النصوص الناقصة بعلامتي __، النصوص الزائدة بـ <<EXTRA>> و <<\/EXTRA>>,
247
- اختلافات المعنى بـ [MEANING] و [/MEANING]،
248
- والأخطاء أو علامات الشك بـ [DOUBT] و [/DOUBT].
249
- */
250
- const ANALYSIS_PROMPT = `أنت خبير لغوي متخصص في مراجعة الترجمة التقنية. مهمتك مقارنة النص المصدر والنص الهدف بدقة عالية وتحليل النص كفقرات منفصلة مع التأكد من أن كل فقرة تنتهي بنقطة. النصوص مليئة بالأخطاء والنواقص.
251
- لا تقم بإزالة أو تعديل العلامات التالية:
252
- • الأرقام والتواريخ: تحافظ على علامات < و >.
253
- • النصوص المفقودة: تحافظ على علامات __ و __.
254
- • النصوص الزائدة: ضعها بين <<EXTRA>> و <<\/EXTRA>>.
255
- • اختلافات المعنى: تحافظ على علامات [MEANING] و [/MEANING].
256
- • علامات الشك أو الأخطاء البسيطة: ضعها بين [DOUBT] و [/DOUBT].
257
-
258
- اعتمد النص المصدر كأساس للمقارنة، وقم بتحديد:
259
- 1. اختلافات الأرقام/التواريخ باستخدام <الرقم/التاريخ_في_المصدر> → <الرقم/التاريخ_في_الهدف>.
260
- 2. النصوص المفقودة كما هي بين علامتي __.
261
- 3. النصوص الزائدة كما هي بين <<EXTRA>> و <<\/EXTRA>>.
262
- 4. اختلافات المعنى باستخدام [MEANING] مع الحفاظ على التعليم.
263
- 5. علامات الشك أو الأخطاء البسيطة باستخدام [DOUBT] مع ضرورة مراجعة دقيقة لتفادي التظليل الوهمي.
264
 
265
  النص المصدر:
266
  {source}
267
 
268
  النص الهدف:
269
  {target}`;
270
-
271
- /* =====================================
272
- دوال مساعدة للتعامل مع النصوص
273
- ===================================== */
274
- // حساب عدد الكلمات في النص
275
  function countWords(text) {
276
  return text.trim().split(/\s+/).filter(word => word !== "").length;
277
  }
278
- // هروب أحرف Regex الخاصة
279
  function escapeRegExp(string) {
280
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
281
  }
282
- // تقسيم النص إلى فقرات مع التأكد من انتهاء كل فقرة بنقطة وترقيمها
283
  function splitIntoLines(text) {
284
  return text.split(/\n+/).map((line, i) => {
285
  line = line.trim();
286
- if(line && !line.endsWith('.')) {
287
- line += '.';
288
- }
289
- return `<div class="line-item"><span class="line-number">${i+1}:</span> <span class="line-text">${line}</span></div>`;
290
  }).join('');
291
  }
292
- // الحصول على رقم السطر لظهور عبارة معينة
293
  function getLineNumber(text, substring) {
294
  const index = text.indexOf(substring);
295
  if (index === -1) return "غير محدد";
296
  return text.substring(0, index).split("\n").length;
297
  }
298
-
299
- /* =====================================
300
- دوال التمييز (Highlighting) للنتائج
301
- ===================================== */
302
  function applyHighlights(originalText, analysisOutput) {
303
  let highlightedText = originalText;
304
  let match;
305
- // تمييز اختلافات الأرقام/التواريخ
306
  const numberRegex = /<([^<>]+)>/g;
307
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
308
  const phrase = match[1].trim();
@@ -312,7 +288,7 @@
312
  highlightedText = highlightedText.replace(phraseRegex, replacement);
313
  }
314
  }
315
- // تمييز النصوص المفقودة
316
  const missingRegex = /__(.*?)__/g;
317
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
318
  const phrase = match[1].trim();
@@ -322,7 +298,7 @@
322
  highlightedText = highlightedText.replace(phraseRegex, replacement);
323
  }
324
  }
325
- // تمييز النصوص الزائدة
326
  const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
327
  while ((match = extraRegex.exec(analysisOutput)) !== null) {
328
  const phrase = match[1].trim();
@@ -332,7 +308,7 @@
332
  highlightedText = highlightedText.replace(phraseRegex, replacement);
333
  }
334
  }
335
- // تمييز اختلافات المعنى
336
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
337
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
338
  const phrase = match[1].trim();
@@ -342,7 +318,7 @@
342
  highlightedText = highlightedText.replace(phraseRegex, replacement);
343
  }
344
  }
345
- // تمييز علامات الشك أو الأخطاء البسيطة
346
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
347
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
348
  const phrase = match[1].trim();
@@ -354,69 +330,64 @@
354
  }
355
  return highlightedText;
356
  }
357
-
358
- /* =====================================
359
- دالة توليد الشرح التفصيلي Organized Explanation
360
- يتم تقسيم الشرح إلى خطوات منظمة
361
- ===================================== */
362
  function generateExplanation(sourceText, analysisOutput) {
363
  let steps = [];
364
  let match;
365
- // الخطوة 1: النصوص المفقودة
 
 
 
 
 
366
  const missingRegex = /__(.*?)__/g;
367
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
368
  const phrase = match[1].trim();
369
  if (phrase) {
370
  const lineNum = getLineNumber(sourceText, phrase);
371
- steps.push(`<li><strong>الخطوة 1:</strong> في السطر ${lineNum}، الجزء "<span class="highlight-missing">__${phrase}__</span>" من النص المصدر مفقود في النص الهدف. تأكد من إضافته لتحسين الدقة.</li>`);
372
  }
373
  }
374
- // الخطوة 2: اختلافات الأرقام/التواريخ
375
  const numberRegex = /<([^<>]+)>/g;
376
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
377
  const phrase = match[1].trim();
378
  if (phrase) {
379
  const lineNum = getLineNumber(sourceText, phrase);
380
- steps.push(`<li><strong>الخطوة 2:</strong> في السطر ${lineNum}، الرقم أو التاريخ "<span class="highlight-number">${phrase}</span>" في المصدر لا يتطابق مع الهدف. يرجى المراجعة.</li>`);
381
  }
382
  }
383
- // الخطوة 3: النصوص الزائدة
384
  const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
385
  while ((match = extraRegex.exec(analysisOutput)) !== null) {
386
  const phrase = match[1].trim();
387
  if (phrase) {
388
  const lineNum = getLineNumber(sourceText, phrase);
389
- steps.push(`<li><strong>تنبيه إضافي:</strong> في السطر ${lineNum}، النص "<span class="highlight-extra">${phrase}</span>" موجود كإضافة غير متوقعة في النص الهدف. يرجى المراجعة.</li>`);
390
  }
391
  }
392
- // الخطوة 4: اختلافات المعنى
393
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
394
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
395
  const phrase = match[1].trim();
396
  if (phrase) {
397
  const lineNum = getLineNumber(sourceText, phrase);
398
- steps.push(`<li><strong>الخطوة 4:</strong> في السطر ${lineNum}، تم العثور على اختلاف في المعنى مع التعبير "<span class="highlight-meaning">${phrase}</span>". تحقق من الدقة.</li>`);
399
  }
400
  }
401
- // الخطوة 5: علامات الشك أو الأخطاء البسيطة
402
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
403
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
404
  const phrase = match[1].trim();
405
  if (phrase) {
406
  const lineNum = getLineNumber(sourceText, phrase);
407
- steps.push(`<li><strong>تنبيه:</strong> في السطر ${lineNum}، تم العثور على علامة شك أو خطأ بسيط "<span class="highlight-doubt">${phrase}</span>". يُنصح بمراجعة علامات الترقيم والأخطاء البسيطة.</li>`);
408
  }
409
  }
410
- // إذا لم يكن هناك اختلافات
411
  if (steps.length === 0) {
412
- return `<p>النصوص متطابقة تماماً ولا توجد فروقات تحتاج للتنبيه.</p>`;
413
  }
414
  return `<ol class="list-decimal ml-6 space-y-2">${steps.join('')}</ol>`;
415
  }
416
-
417
- /* =====================================
418
- دالة معالجة الملفات (PDF و DOCX)
419
- ===================================== */
420
  async function processFile(file) {
421
  let text = "";
422
  if (file.type === 'application/pdf') {
@@ -438,11 +409,8 @@
438
  }
439
  return text;
440
  }
441
-
442
- /* =====================================
443
- دوال رفع الملفات وإدخال النصوص
444
- ===================================== */
445
- // رفع ملف السورس
446
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
447
  const file = event.target.files[0];
448
  if (!file) return;
@@ -452,12 +420,11 @@
452
  document.getElementById('sourceText').value = text;
453
  } catch (error) {
454
  console.error('Error processing source file:', error);
455
- addError('خطأ في معالجة ملف السورس');
456
  } finally {
457
  document.getElementById('processStatus').classList.add('hidden');
458
  }
459
  });
460
- // رفع ملف التارجت
461
  document.getElementById('targetFile')?.addEventListener('change', async (event) => {
462
  const file = event.target.files[0];
463
  if (!file) return;
@@ -467,12 +434,11 @@
467
  document.getElementById('targetText').value = text;
468
  } catch (error) {
469
  console.error('Error processing target file:', error);
470
- addError('خطأ في معالجة ملف التارجت');
471
  } finally {
472
  document.getElementById('processStatus').classList.add('hidden');
473
  }
474
  });
475
- // رفع ملف المصادر الإضافية
476
  document.getElementById('sourceExtraFile')?.addEventListener('change', async (event) => {
477
  const file = event.target.files[0];
478
  if (!file) return;
@@ -487,29 +453,24 @@
487
  document.getElementById('processStatus').classList.add('hidden');
488
  }
489
  });
490
-
491
- /* =====================================
492
- دالة عرض الأخطاء والرسائل
493
- ===================================== */
494
  function addError(message, type = 'error') {
495
  const errorsList = document.getElementById('errorsList');
496
  if (!errorsList) return;
497
  const errorDiv = document.createElement('div');
498
  errorDiv.className = `p-4 rounded-xl ${type === 'error' ? 'bg-red-50 text-red-700' : 'bg-yellow-50 text-yellow-700'}`;
499
  errorDiv.innerHTML = `<div class="flex items-center">
500
- <i class="fas fa-${type === 'error' ? 'exclamation-circle' : 'info-circle'} ml-2 text-${type === 'error' ? 'red' : 'yellow'}-500"></i>
501
  <span>${message}</span>
502
  </div>`;
503
  errorsList.appendChild(errorDiv);
504
  }
505
-
506
- /* =====================================
507
- معالجة عملية التحليل عند الضغط على الزر
508
- ===================================== */
509
  document.getElementById('submitBtn').addEventListener('click', async () => {
510
  const sourceText = document.getElementById('sourceText').value;
511
  const targetText = document.getElementById('targetText').value;
512
- // مسح الرسائل السابقة وإظهار النتائج
513
  document.getElementById('errorsList').innerHTML = '';
514
  document.getElementById('resultSection').classList.remove('hidden');
515
  document.getElementById('explanationBox').classList.remove('hidden');
@@ -519,7 +480,6 @@
519
  return;
520
  }
521
 
522
- // مقارنة عدد الكلمات وتنبيه إن وجد اختلاف
523
  const sourceWordCount = countWords(sourceText);
524
  const targetWordCount = countWords(targetText);
525
  if (sourceWordCount !== targetWordCount) {
@@ -527,25 +487,22 @@
527
  }
528
 
529
  try {
530
- // عرض مؤشر التقدم
531
  const progressDiv = document.createElement('div');
532
  progressDiv.className = "bg-indigo-100 p-4 rounded-xl mb-4";
533
  progressDiv.innerHTML = `<div class="flex items-center">
534
- <div class="animate-spin h-6 w-6 border-4 border-indigo-600 rounded-full border-t-transparent ml-3"></div>
535
  <span>جارٍ التحليل...</span>
536
  </div>`;
537
  document.getElementById('errorsList').appendChild(progressDiv);
538
-
539
- // بناء الـ prompt باستخدام النصين المُدخلين
540
  const prompt = ANALYSIS_PROMPT
541
  .replace("{source}", sourceText)
542
  .replace("{target}", targetText);
543
 
544
- // استدعاء DeepSeek API
545
  const payload = {
546
  model: "deepseek-chat",
547
  messages: [
548
- { role: "system", content: "أنت خبير في تحليل النصوص ومقارنتها بدقة عالية." },
549
  { role: "user", content: prompt }
550
  ],
551
  temperature: 0.3,
@@ -560,47 +517,41 @@
560
  },
561
  body: JSON.stringify(payload)
562
  });
563
- if (!response.ok) {
564
- throw new Error('حدث خطأ بالشبكة: ' + response.statusText);
565
- }
566
  const data = await response.json();
567
  const analysisOutput = data.choices[0].message.content.trim();
568
  progressDiv.remove();
569
 
570
- // إذا كانت النصوص متطابقة تمامًا
571
  if (analysisOutput.includes('[MATCH]')) {
572
  const checkDiv = document.createElement('div');
573
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
574
- checkDiv.innerHTML = `<i class="fas fa-check-circle ml-2 text-lg"></i> <span class="text-lg">النصوص متطابقة تماماً</span>`;
575
  document.getElementById('errorsList').appendChild(checkDiv);
576
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
577
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
578
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه.</p>`;
579
  } else {
580
- // تطبيق التحديد على النصوص
581
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
582
  const targetHighlighted = applyHighlights(targetText, analysisOutput);
583
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
584
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
585
- // توليد شرح منظم على شكل خطوات
586
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
587
  document.getElementById('explanationText').innerHTML = explanationHTML;
588
 
589
- // عرض ملخص ��لاختلافات في الأسفل (اختياري)
590
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
591
  const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
592
  const extraDiffCount = (analysisOutput.match(/<<EXTRA>>(.*?)<<\/EXTRA>>/g) || []).length;
593
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
594
  const doubtDiffCount = (analysisOutput.match(/\[DOUBT\](.*?)\[\/DOUBT\]/g) || []).length;
595
- if (numDiffCount > 0 || missingDiffCount > 0 || extraDiffCount > 0 || meaningDiffCount > 0 || doubtDiffCount > 0) {
596
  const summaryDiv = document.createElement('div');
597
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
598
- let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc mr-6 space-y-1">';
599
- if (numDiffCount > 0) summaryText += `<li>اختلاف في الأرقام/التواريخ: ${numDiffCount}</li>`;
600
- if (missingDiffCount > 0) summaryText += `<li>النصوص المفقودة: ${missingDiffCount}</li>`;
601
- if (extraDiffCount > 0) summaryText += `<li>النصوص الزائدة: ${extraDiffCount}</li>`;
602
- if (meaningDiffCount > 0) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
603
- if (doubtDiffCount > 0) summaryText += `<li>علامات الشك أو الأخطاء البسيطة: ${doubtDiffCount}</li>`;
604
  summaryText += '</ul>';
605
  summaryDiv.innerHTML = summaryText;
606
  document.getElementById('errorsList').appendChild(summaryDiv);
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>نظام المقارنة والتحليل المتقدم - شركة موندو لينجوا</title>
7
  <!-- استيراد مكتبات Tailwind وFont Awesome وMammoth -->
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script>
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
11
  <style>
12
  /* ================================
13
+ الحركات والتأثيرات
14
  ================================= */
15
  @keyframes gradient {
16
  0% { background-position: 0% 50%; }
 
30
  70% { box-shadow: 0 0 0 10px rgba(156,39,176,0); }
31
  100% { box-shadow: 0 0 0 0 rgba(156,39,176,0); }
32
  }
33
+
34
  /* ================================
35
+ تنسيقات النص والتظليل
36
  ================================= */
37
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
38
  .highlight-number {
 
62
  font-weight: bold;
63
  }
64
  .highlight-doubt {
65
+ background-color: #DBEAFE; /* أزرق لعلامات الشك */
66
  color: #1E3A8A;
67
  padding: 0 4px;
68
  border-radius: 3px;
69
  font-weight: bold;
70
  }
71
+
72
  /* ================================
73
+ تنسيق الفقرات وترقيمها
74
  ================================= */
 
 
 
 
 
75
  .line-item {
76
+ margin-bottom: 1rem;
77
+ padding: 0.5rem;
78
+ border-bottom: 1px dashed #ccc;
79
  }
80
  .line-number {
 
81
  font-weight: bold;
82
  color: #4B5563;
83
+ margin-left: 0.5rem;
84
  }
85
+ .line-text { display: inline-block; }
86
+
87
  /* ================================
88
+ تحسين تصميم البطاقات والأيقونات
89
  ================================= */
90
+ .card {
91
+ background-color: #fff;
92
+ border-radius: 1rem;
93
+ box-shadow: 0 10px 25px -5px rgba(156,39,176,0.1);
94
+ padding: 2rem;
95
+ border: 1px solid #f3f4f6;
96
  }
97
  .card-hover:hover {
98
+ box-shadow: 0 10px 25px -5px rgba(156,39,176,0.2);
99
+ transform: translateY(-3px);
100
  }
101
+ .icon { margin-right: 0.5rem; }
102
  </style>
103
  </head>
104
  <body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
105
  <div class="min-h-screen pb-12">
106
+ <!-- رأس الصفحة -->
107
  <header class="bg-gradient-to-r from-indigo-700 via-purple-700 to-pink-700 animate-gradient text-white py-10 mb-10 shadow-xl">
108
+ <div class="max-w-6xl mx-auto px-4 text-center">
109
+ <h1 class="text-5xl font-bold mb-4 animate-scale">
110
+ <i class="fas fa-chart-line icon"></i> نظام المقارنة والتحليل المتقدم
111
+ </h1>
112
+ <p class="text-xl opacity-90">
113
+ <i class="fas fa-info-circle icon"></i> دقة عالية في استخراج وتحليل النصوص
114
+ </p>
115
  </div>
116
  </header>
117
 
118
+ <!-- المحتوى الرئيسي -->
119
+ <main class="max-w-6xl mx-auto px-4 space-y-8">
120
  <!-- قسم رفع الملفات -->
121
+ <div class="card card-hover">
122
+ <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
123
+ <i class="fas fa-file-upload icon text-indigo-600"></i> تحميل الملفات
124
  </h2>
125
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
126
+ <!-- ملف المصدر -->
127
+ <div class="group border-2 border-dashed border-indigo-300 rounded-xl p-8 text-center bg-indigo-50 hover:bg-indigo-100 transition-colors duration-300">
128
  <label class="cursor-pointer block">
129
  <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
130
+ <i class="fas fa-upload text-5xl text-indigo-500 mb-4"></i>
131
+ <span class="text-lg text-indigo-600 group-hover:text-indigo-700">ملف المصدر</span>
132
  </label>
133
  </div>
134
+ <!-- ملف الهدف -->
135
+ <div class="group border-2 border-dashed border-pink-300 rounded-xl p-8 text-center bg-pink-50 hover:bg-pink-100 transition-colors duration-300">
136
  <label class="cursor-pointer block">
137
  <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
138
+ <i class="fas fa-download text-5xl text-pink-500 mb-4"></i>
139
+ <span class="text-lg text-pink-600 group-hover:text-pink-700">ملف الهدف</span>
140
  </label>
141
  </div>
142
  </div>
 
149
  </div>
150
 
151
  <!-- قسم إدخال النصوص يدويًا -->
152
+ <div class="card card-hover">
153
  <div class="space-y-6">
154
  <!-- النص المصدر -->
155
  <div class="group">
156
+ <label class="block text-lg font-bold text-gray-700 mb-3">
157
+ <i class="fas fa-language icon text-indigo-600"></i> النص المصدر
158
  </label>
159
  <textarea id="sourceText" dir="rtl" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
160
  </div>
161
  <!-- النص الهدف -->
162
  <div class="group">
163
+ <label class="block text-lg font-bold text-gray-700 mb-3">
164
+ <i class="fas fa-language icon text-pink-600"></i> النص الهدف
165
  </label>
166
  <textarea id="targetText" dir="ltr" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-pink-200 focus:border-pink-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
167
  </div>
 
169
  </div>
170
 
171
  <!-- قسم المصادر الإضافية -->
172
+ <div class="card card-hover">
173
+ <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
174
+ <i class="fas fa-book-open icon text-green-600"></i> مصادر إضافية
175
  </h2>
176
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
177
  <!-- رفع ملف المصادر الإضافية -->
178
+ <div class="group border-2 border-dashed border-green-300 rounded-xl p-8 text-center bg-green-50 hover:bg-green-100 transition-colors duration-300">
179
  <label class="cursor-pointer block">
180
  <input type="file" id="sourceExtraFile" accept=".docx,.pdf" class="hidden">
181
  <i class="fas fa-upload text-5xl text-green-500 mb-4"></i>
 
184
  </div>
185
  <!-- إدخال المصادر يدويًا -->
186
  <div class="group">
187
+ <label class="block text-lg font-bold text-gray-700 mb-3">
188
+ <i class="fas fa-edit icon text-green-600"></i> إدخال المصادر يدويًا
189
  </label>
190
  <textarea id="sourceExtraText" dir="rtl" class="w-full px-6 py-4 border-2 border-green-200 rounded-xl focus:ring-green-200 focus:border-green-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب المصادر هنا..."></textarea>
191
  </div>
192
  </div>
193
  </div>
194
 
195
+ <!-- زر التحليل والمراجعة -->
196
+ <button id="submitBtn" class="w-full bg-gradient-to-r from-indigo-600 to-pink-600 hover:from-indigo-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-xl transition-all transform hover:scale-105 focus:ring-indigo-200 text-xl shadow-lg hover:shadow-xl pulse-animation">
197
  <div class="flex items-center justify-center">
198
+ <i class="fas fa-sync-alt icon ml-2"></i> تحليل ومراجعة النصوص
199
  </div>
200
  </button>
201
 
202
+ <!-- نتائج التحليل -->
203
+ <div id="resultSection" class="card hidden">
204
+ <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
205
+ <i class="fas fa-search icon text-green-600"></i> نتائج التحليل والمقارنة
206
  </h2>
207
  <div id="errorsList" class="space-y-3 mb-6"></div>
208
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
 
209
  <div>
210
+ <h4 class="text-lg font-bold text-gray-700 mb-3">
211
+ <i class="fas fa-file-alt icon text-indigo-600"></i> النص المصدر (مع التعليم)
212
  </h4>
213
  <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-6 min-h-[200px] border-2 border-indigo-100 text-comparison"></div>
214
  </div>
 
215
  <div>
216
+ <h4 class="text-lg font-bold text-gray-700 mb-3">
217
+ <i class="fas fa-file-alt icon text-pink-600"></i> النص الهدف (مع التعليم)
218
  </h4>
219
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
220
  </div>
221
  </div>
222
  </div>
223
 
224
+ <!-- شرح تفصيلي للاختلافات -->
225
+ <div id="explanationBox" class="card hidden">
226
+ <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
227
+ <i class="fas fa-info-circle icon text-green-600"></i> شرح الاختلافات
228
  </h2>
229
  <div id="explanationText" class="text-lg text-gray-700"></div>
230
  </div>
 
232
  </div>
233
 
234
  <!-- ================================
235
+ جافا سكريبت: الوظائف والتحليل
236
  ================================= -->
237
  <script>
 
238
  const API_URL = 'https://api.deepseek.com/chat/completions';
239
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
240
+ const ANALYSIS_PROMPT = `أنت خبير لغوي وتقني متخصص في مراجعة الترجمة التقنية وتحليل النصوص بدقة. مهمتك مقارنة النص المصدر والنص الهدف واستخراج الاختلافات بدقة مع تحسين التظليل والتعليم.
241
+ تعليمات:
242
+ 1. قم بتحليل النص إلى فقرات منفصلة، مع التأكد من انتهاء كل فقرة بنقطة.
243
+ 2. لا تقم بتعديل العلامات التالية:
244
+ - الأرقام والتواريخ محاطة بـ < و >.
245
+ - النصوص المفقودة محاطة بـ __ و __.
246
+ - النصوص الزائدة محاطة بـ <<EXTRA>> و <<\/EXTRA>>.
247
+ - اختلافات المعنى محاطة بـ [MEANING] و [/MEANING].
248
+ - علامات الشك أو الأخطاء البسيطة محاطة بـ [DOUBT] و [/DOUBT].
249
+ 3. يجب أن يقدم التحليل تعليمات دقيقة مع أيقونات توضيحية لكل نوع من الاختلافات.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
251
  النص المصدر:
252
  {source}
253
 
254
  النص الهدف:
255
  {target}`;
256
+
257
+ // دوال مساعدة
 
 
 
258
  function countWords(text) {
259
  return text.trim().split(/\s+/).filter(word => word !== "").length;
260
  }
 
261
  function escapeRegExp(string) {
262
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
263
  }
 
264
  function splitIntoLines(text) {
265
  return text.split(/\n+/).map((line, i) => {
266
  line = line.trim();
267
+ if(line && !line.endsWith('.')) { line += '.'; }
268
+ return `<div class="line-item"><span class="line-number">${i+1}:</span><span class="line-text">${line}</span></div>`;
 
 
269
  }).join('');
270
  }
 
271
  function getLineNumber(text, substring) {
272
  const index = text.indexOf(substring);
273
  if (index === -1) return "غير محدد";
274
  return text.substring(0, index).split("\n").length;
275
  }
276
+
277
+ // دوال التظليل (Highlighting)
 
 
278
  function applyHighlights(originalText, analysisOutput) {
279
  let highlightedText = originalText;
280
  let match;
281
+ // اختلافات الأرقام/التواريخ
282
  const numberRegex = /<([^<>]+)>/g;
283
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
284
  const phrase = match[1].trim();
 
288
  highlightedText = highlightedText.replace(phraseRegex, replacement);
289
  }
290
  }
291
+ // النصوص المفقودة
292
  const missingRegex = /__(.*?)__/g;
293
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
294
  const phrase = match[1].trim();
 
298
  highlightedText = highlightedText.replace(phraseRegex, replacement);
299
  }
300
  }
301
+ // النصوص الزائدة
302
  const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
303
  while ((match = extraRegex.exec(analysisOutput)) !== null) {
304
  const phrase = match[1].trim();
 
308
  highlightedText = highlightedText.replace(phraseRegex, replacement);
309
  }
310
  }
311
+ // اختلافات المعنى
312
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
313
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
314
  const phrase = match[1].trim();
 
318
  highlightedText = highlightedText.replace(phraseRegex, replacement);
319
  }
320
  }
321
+ // علامات الشك أو الأخطاء البسيطة
322
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
323
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
324
  const phrase = match[1].trim();
 
330
  }
331
  return highlightedText;
332
  }
333
+
334
+ // دالة توليد شرح تفصيلي للاختلافات مع أيقونات
 
 
 
335
  function generateExplanation(sourceText, analysisOutput) {
336
  let steps = [];
337
  let match;
338
+ const iconMissing = `<i class="fas fa-exclamation-triangle text-red-500 mr-1"></i>`;
339
+ const iconNumber = `<i class="fas fa-hashtag text-yellow-600 mr-1"></i>`;
340
+ const iconExtra = `<i class="fas fa-plus-circle text-green-600 mr-1"></i>`;
341
+ const iconMeaning = `<i class="fas fa-info-circle text-blue-600 mr-1"></i>`;
342
+ const iconDoubt = `<i class="fas fa-question-circle text-indigo-600 mr-1"></i>`;
343
+
344
  const missingRegex = /__(.*?)__/g;
345
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
346
  const phrase = match[1].trim();
347
  if (phrase) {
348
  const lineNum = getLineNumber(sourceText, phrase);
349
+ steps.push(`<li>${iconMissing} في السطر ${lineNum}، النص المفقود: <span class="highlight-missing">__${phrase}__</span> غير موجود في النص الهدف.</li>`);
350
  }
351
  }
 
352
  const numberRegex = /<([^<>]+)>/g;
353
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
354
  const phrase = match[1].trim();
355
  if (phrase) {
356
  const lineNum = getLineNumber(sourceText, phrase);
357
+ steps.push(`<li>${iconNumber} في السطر ${lineNum}، الرقم/التاريخ: <span class="highlight-number">${phrase}</span> لا يتطابق بين المصدر والهدف.</li>`);
358
  }
359
  }
 
360
  const extraRegex = /<<EXTRA>>(.*?)<<\/EXTRA>>/g;
361
  while ((match = extraRegex.exec(analysisOutput)) !== null) {
362
  const phrase = match[1].trim();
363
  if (phrase) {
364
  const lineNum = getLineNumber(sourceText, phrase);
365
+ steps.push(`<li>${iconExtra} في السطر ${lineNum}، النص الزائد: <span class="highlight-extra">${phrase}</span> موجود بشكل غير متوقع في النص الهدف.</li>`);
366
  }
367
  }
 
368
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
369
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
370
  const phrase = match[1].trim();
371
  if (phrase) {
372
  const lineNum = getLineNumber(sourceText, phrase);
373
+ steps.push(`<li>${iconMeaning} في السطر ${lineNum}، اختلاف في المعنى: <span class="highlight-meaning">${phrase}</span> بين المصدر والهدف.</li>`);
374
  }
375
  }
 
376
  const doubtRegex = /\[DOUBT\](.*?)\[\/DOUBT\]/g;
377
  while ((match = doubtRegex.exec(analysisOutput)) !== null) {
378
  const phrase = match[1].trim();
379
  if (phrase) {
380
  const lineNum = getLineNumber(sourceText, phrase);
381
+ steps.push(`<li>${iconDoubt} في السطر ${lineNum}، علامة شك: <span class="highlight-doubt">${phrase}</span> قد تشير إلى غموض أو خطأ بسيط يحتاج مراجعة.</li>`);
382
  }
383
  }
 
384
  if (steps.length === 0) {
385
+ return `<p class="text-green-700"><i class="fas fa-check-circle mr-2"></i> لا توجد اختلافات ملحوظة بين النصين.</p>`;
386
  }
387
  return `<ol class="list-decimal ml-6 space-y-2">${steps.join('')}</ol>`;
388
  }
389
+
390
+ // دالة معالجة الملفات (PDF و DOCX)
 
 
391
  async function processFile(file) {
392
  let text = "";
393
  if (file.type === 'application/pdf') {
 
409
  }
410
  return text;
411
  }
412
+
413
+ // رفع الملفات وإدخال النصوص
 
 
 
414
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
415
  const file = event.target.files[0];
416
  if (!file) return;
 
420
  document.getElementById('sourceText').value = text;
421
  } catch (error) {
422
  console.error('Error processing source file:', error);
423
+ addError('خطأ في معالجة ملف المصدر');
424
  } finally {
425
  document.getElementById('processStatus').classList.add('hidden');
426
  }
427
  });
 
428
  document.getElementById('targetFile')?.addEventListener('change', async (event) => {
429
  const file = event.target.files[0];
430
  if (!file) return;
 
434
  document.getElementById('targetText').value = text;
435
  } catch (error) {
436
  console.error('Error processing target file:', error);
437
+ addError('خطأ في معالجة ملف الهدف');
438
  } finally {
439
  document.getElementById('processStatus').classList.add('hidden');
440
  }
441
  });
 
442
  document.getElementById('sourceExtraFile')?.addEventListener('change', async (event) => {
443
  const file = event.target.files[0];
444
  if (!file) return;
 
453
  document.getElementById('processStatus').classList.add('hidden');
454
  }
455
  });
456
+
457
+ // دالة عرض الأخطاء
 
 
458
  function addError(message, type = 'error') {
459
  const errorsList = document.getElementById('errorsList');
460
  if (!errorsList) return;
461
  const errorDiv = document.createElement('div');
462
  errorDiv.className = `p-4 rounded-xl ${type === 'error' ? 'bg-red-50 text-red-700' : 'bg-yellow-50 text-yellow-700'}`;
463
  errorDiv.innerHTML = `<div class="flex items-center">
464
+ <i class="fas fa-${type === 'error' ? 'exclamation-circle' : 'info-circle'} mr-2"></i>
465
  <span>${message}</span>
466
  </div>`;
467
  errorsList.appendChild(errorDiv);
468
  }
469
+
470
+ // معالجة عملية التحليل عند الضغط على الزر
 
 
471
  document.getElementById('submitBtn').addEventListener('click', async () => {
472
  const sourceText = document.getElementById('sourceText').value;
473
  const targetText = document.getElementById('targetText').value;
 
474
  document.getElementById('errorsList').innerHTML = '';
475
  document.getElementById('resultSection').classList.remove('hidden');
476
  document.getElementById('explanationBox').classList.remove('hidden');
 
480
  return;
481
  }
482
 
 
483
  const sourceWordCount = countWords(sourceText);
484
  const targetWordCount = countWords(targetText);
485
  if (sourceWordCount !== targetWordCount) {
 
487
  }
488
 
489
  try {
 
490
  const progressDiv = document.createElement('div');
491
  progressDiv.className = "bg-indigo-100 p-4 rounded-xl mb-4";
492
  progressDiv.innerHTML = `<div class="flex items-center">
493
+ <div class="animate-spin h-6 w-6 border-4 border-indigo-600 rounded-full border-t-transparent mr-3"></div>
494
  <span>جارٍ التحليل...</span>
495
  </div>`;
496
  document.getElementById('errorsList').appendChild(progressDiv);
497
+
 
498
  const prompt = ANALYSIS_PROMPT
499
  .replace("{source}", sourceText)
500
  .replace("{target}", targetText);
501
 
 
502
  const payload = {
503
  model: "deepseek-chat",
504
  messages: [
505
+ { role: "system", content: "أنت خبير في تحليل ومراجعة النصوص بدقة عالية." },
506
  { role: "user", content: prompt }
507
  ],
508
  temperature: 0.3,
 
517
  },
518
  body: JSON.stringify(payload)
519
  });
520
+ if (!response.ok) { throw new Error('حدث خطأ بالشبكة: ' + response.statusText); }
 
 
521
  const data = await response.json();
522
  const analysisOutput = data.choices[0].message.content.trim();
523
  progressDiv.remove();
524
 
 
525
  if (analysisOutput.includes('[MATCH]')) {
526
  const checkDiv = document.createElement('div');
527
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
528
+ checkDiv.innerHTML = `<i class="fas fa-check-circle mr-2"></i> <span>النصوص متطابقة تماماً</span>`;
529
  document.getElementById('errorsList').appendChild(checkDiv);
530
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
531
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
532
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه.</p>`;
533
  } else {
 
534
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
535
  const targetHighlighted = applyHighlights(targetText, analysisOutput);
536
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
537
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
 
538
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
539
  document.getElementById('explanationText').innerHTML = explanationHTML;
540
 
 
541
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
542
  const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
543
  const extraDiffCount = (analysisOutput.match(/<<EXTRA>>(.*?)<<\/EXTRA>>/g) || []).length;
544
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
545
  const doubtDiffCount = (analysisOutput.match(/\[DOUBT\](.*?)\[\/DOUBT\]/g) || []).length;
546
+ if (numDiffCount || missingDiffCount || extraDiffCount || meaningDiffCount || doubtDiffCount) {
547
  const summaryDiv = document.createElement('div');
548
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
549
+ let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc ml-4 space-y-1">';
550
+ if (numDiffCount) summaryText += `<li>اختلاف في الأرقام/التواريخ: ${numDiffCount}</li>`;
551
+ if (missingDiffCount) summaryText += `<li>النصوص المفقودة: ${missingDiffCount}</li>`;
552
+ if (extraDiffCount) summaryText += `<li>النصوص الزائدة: ${extraDiffCount}</li>`;
553
+ if (meaningDiffCount) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
554
+ if (doubtDiffCount) summaryText += `<li>علامات الشك: ${doubtDiffCount}</li>`;
555
  summaryText += '</ul>';
556
  summaryDiv.innerHTML = summaryText;
557
  document.getElementById('errorsList').appendChild(summaryDiv);