joermd commited on
Commit
b09b208
·
verified ·
1 Parent(s): 85521cb

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +406 -273
index.html CHANGED
@@ -1,300 +1,433 @@
1
  <!DOCTYPE html>
2
  <html lang="ar" dir="rtl">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>تطبيق مراجعة النصوص</title>
7
- <style>
8
- body {
9
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
- line-height: 1.6;
11
- margin: 0;
12
- padding: 20px;
13
- background-color: #f5f5f5;
14
- color: #333;
15
- }
16
- .container {
17
- max-width: 1200px;
18
- margin: 0 auto;
19
- background: white;
20
- padding: 20px;
21
- border-radius: 8px;
22
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
23
- }
24
- h1 {
25
- color: #2c3e50;
26
- text-align: center;
27
- margin-bottom: 30px;
28
- }
29
- .text-areas {
30
- display: flex;
31
- flex-direction: row;
32
- gap: 20px;
33
- margin-bottom: 20px;
34
- }
35
- .text-column {
36
- flex: 1;
37
- display: flex;
38
- flex-direction: column;
39
- }
40
- label {
41
- font-weight: bold;
42
- margin-bottom: 5px;
43
- color: #2c3e50;
44
- }
45
- textarea {
46
- height: 300px;
47
- padding: 10px;
48
- border: 1px solid #ddd;
49
- border-radius: 4px;
50
- resize: vertical;
51
- font-size: 16px;
52
- font-family: inherit;
53
- }
54
- button {
55
- background-color: #3498db;
56
- color: white;
57
- border: none;
58
- padding: 10px 20px;
59
- border-radius: 4px;
60
- cursor: pointer;
61
- font-size: 16px;
62
- transition: background-color 0.3s;
63
- }
64
- button:hover {
65
- background-color: #2980b9;
66
- }
67
- .result, .explanation {
68
- margin-top: 30px;
69
- padding: 20px;
70
- border: 1px solid #ddd;
71
- border-radius: 4px;
72
- background-color: #f9f9f9;
73
- }
74
- .result h2, .explanation h2 {
75
- color: #2c3e50;
76
- margin-top: 0;
77
- }
78
- .spinner {
79
- display: none;
80
- margin: 20px auto;
81
- width: 50px;
82
- height: 50px;
83
- border: 5px solid #f3f3f3;
84
- border-top: 5px solid #3498db;
85
- border-radius: 50%;
86
- animation: spin 1s linear infinite;
87
- }
88
- @keyframes spin {
89
- 0% { transform: rotate(0deg); }
90
- 100% { transform: rotate(360deg); }
91
- }
92
- .diff-highlight {
93
- display: inline;
94
- padding: 2px 0;
95
- }
96
- .diff-added {
97
- background-color: #c8e6c9;
98
- }
99
- .diff-removed {
100
- background-color: #ffcdd2;
101
- text-decoration: line-through;
102
- }
103
- .diff-changed {
104
- background-color: #fff9c4;
105
- border: 1px dashed #f39c12;
106
- }
107
- .api-key-section {
108
- margin-bottom: 20px;
109
- }
110
- .error-message {
111
- color: #e74c3c;
112
- margin-top: 10px;
113
- }
114
- </style>
 
 
 
115
  </head>
116
- <body>
117
- <div class="container">
118
- <h1>تطبيق مراجعة النصوص</h1>
119
-
120
- <div class="api-key-section">
121
- <label for="apiKey">مفتاح API (يمكنك تعديله إذا لزم الأمر):</label>
122
- <input type="text" id="apiKey" value="sk-21a46269cd8e449f8aeb0cc129c36c33" style="width: 100%; padding: 8px; margin-top: 5px;">
 
 
 
 
 
 
 
 
 
 
 
 
123
  </div>
124
-
125
- <div class="text-areas">
126
- <div class="text-column">
127
- <label for="sourceText">النص المصدر (الأساسي):</label>
128
- <textarea id="sourceText" placeholder="أدخل النص المصدر هنا..."></textarea>
129
- </div>
130
- <div class="text-column">
131
- <label for="targetText">النص الهدف (المشكوك فيه):</label>
132
- <textarea id="targetText" placeholder="أدخل النص الهدف هنا..."></textarea>
133
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  </div>
135
-
136
- <div style="text-align: center;">
137
- <button id="compareButton">قارن النصوص</button>
 
 
138
  </div>
139
-
140
- <div id="spinner" class="spinner"></div>
141
-
142
- <div id="errorMessage" class="error-message"></div>
143
-
144
- <!-- قسم عرض نتائج المقارنة -->
145
- <div id="result" class="result" style="display: none;">
146
- <h2>نتائج المقارنة:</h2>
147
- <div id="comparisonResults"></div>
 
 
 
 
 
 
 
 
 
 
148
  </div>
149
-
150
- <!-- قسم عرض الشرح إذا وُجد -->
151
- <div id="explanation" class="explanation" style="display: none;">
152
- <h2>شرح النتائج:</h2>
153
- <div id="explanationContent"></div>
 
 
 
154
  </div>
155
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- <script>
158
- document.getElementById('compareButton').addEventListener('click', async function() {
159
- const sourceText = document.getElementById('sourceText').value.trim();
160
- const targetText = document.getElementById('targetText').value.trim();
161
- const apiKey = document.getElementById('apiKey').value.trim();
162
- const errorMessageElement = document.getElementById('errorMessage');
163
- const resultElement = document.getElementById('result');
164
- const comparisonResultsElement = document.getElementById('comparisonResults');
165
- const explanationElement = document.getElementById('explanation');
166
- const explanationContentElement = document.getElementById('explanationContent');
167
- const spinner = document.getElementById('spinner');
168
-
169
- errorMessageElement.textContent = '';
170
- resultElement.style.display = 'none';
171
- explanationElement.style.display = 'none';
172
-
173
- if (!sourceText || !targetText) {
174
- errorMessageElement.textContent = 'الرجاء إدخال كلا النصين للمقارنة';
175
- return;
176
- }
177
-
178
- if (!apiKey) {
179
- errorMessageElement.textContent = 'الرجاء إدخال مفتاح API صالح';
180
- return;
181
- }
182
-
183
- spinner.style.display = 'block';
184
-
185
- try {
186
- // تحديث الطلب ليشمل توجيه للموديل بوضع الاختلافات داخل << >>
187
- const prompt = `
188
  قارن بين النص المصدر والنص الهدف وحدد الاختلافات بينهما، بما في ذلك:
189
  1. الأرقام المكتوبة بشكل خاطئ
190
  2. النصوص المفقودة
191
  3. النصوص الفاسدة أو غير المفهومة
192
  4. النصوص المختلفة في المعنى
193
 
194
- يرجى وضع النصوص المختلفة أو التي بها خطأ داخل علامتي << و >>.
195
- كما يُرجى إضافة قسم "الشرح:" في نهاية التحليل يوضح أسباب الاختلاف وأهميتها.
196
 
197
  النص المصدر:
198
  ${sourceText}
199
 
200
  النص الهدف:
201
  ${targetText}
202
- `;
203
-
204
- const response = await fetch('https://api.deepseek.com/chat/completions', {
205
- method: 'POST',
206
- headers: {
207
- 'Content-Type': 'application/json',
208
- 'Authorization': `Bearer ${apiKey}`
209
- },
210
- body: JSON.stringify({
211
- model: 'deepseek-reasoner',
212
- messages: [
213
- { role: 'system', content: 'أنت مساعد مفيد متخصص في مراجعة النصوص وتحديد الاختلافات بينها بدقة عالية.' },
214
- { role: 'user', content: prompt }
215
- ],
216
- stream: false
217
- })
218
- });
219
-
220
- if (!response.ok) {
221
- throw new Error(`خطأ في الاتصال بالـ API: ${response.status} ${response.statusText}`);
222
- }
223
-
224
- const data = await response.json();
225
- const analysisResult = data.choices[0].message.content;
226
-
227
- // فصل التحليل عن قسم الشرح إن وُجد
228
- let analysisPart = analysisResult;
229
- let explanationPart = '';
230
- if (analysisResult.includes('الشرح:')) {
231
- const splitParts = analysisResult.split('الشرح:');
232
- analysisPart = splitParts[0];
233
- explanationPart = splitParts[1];
234
- }
235
-
236
- comparisonResultsElement.innerHTML = formatAnalysisResult(analysisPart, sourceText, targetText);
237
-
238
- if(explanationPart.trim()){
239
- explanationContentElement.innerHTML = explanationPart.replace(/\n/g, '<br>');
240
- explanationElement.style.display = 'block';
241
- }
242
-
243
- resultElement.style.display = 'block';
244
- } catch (error) {
245
- errorMessageElement.textContent = `حدث خطأ: ${error.message}`;
246
- console.error('Error:', error);
247
- } finally {
248
- spinner.style.display = 'none';
249
- }
250
  });
251
 
252
- function formatAnalysisResult(analysisText, sourceText, targetText) {
253
- // تحويل النص إلى HTML مع إبراز الاختلافات والتظليل:
254
- let formattedText = analysisText
255
- .replace(/\n/g, '<br>')
256
- .replace(/الأرقام المكتوبة بشكل خاطئ:|الأرقام غير الصحيحة:/gi, '<strong style="color: #e74c3c;">الأرقام المكتوبة بشكل خاطئ:</strong>')
257
- .replace(/النصوص المفقودة:/gi, '<strong style="color: #e74c3c;">النصوص المفقودة:</strong>')
258
- .replace(/النصوص الفاسدة:|النصوص غير المفهومة:/gi, '<strong style="color: #e74c3c;">النصوص الفاسدة:</strong>')
259
- .replace(/النصوص المختلفة في المعنى:/gi, '<strong style="color: #e74c3c;">النصوص المختلفة في المعنى:</strong>');
260
-
261
- // إبراز النصوص داخل علامتي << >>
262
- formattedText = formattedText.replace(/<<(.+?)>>/g, '<span class="diff-highlight diff-changed"><<$1>></span>');
263
-
264
- // إبراز الاختلافات بناءً على موقعها في النص المصدر أو النص الهدف
265
- formattedText = formattedText
266
- .replace(/في النص المصدر: "(.*?)"/g, 'في النص المصدر: "<span class="diff-highlight diff-removed">$1</span>"')
267
- .replace(/في النص الهدف: "(.*?)"/g, 'في النص الهدف: "<span class="diff-highlight diff-added">$1</span>"');
268
-
269
- // إضافة مقارنة سطرية للمعاينة
270
- const sourceLines = sourceText.split('\n');
271
- const targetLines = targetText.split('\n');
272
- const maxLines = Math.max(sourceLines.length, targetLines.length);
273
-
274
- let visualComparison = '<h3>المقارنة السطرية:</h3><div style="display: flex; gap: 20px;">';
275
-
276
- // عمود النص المصدر
277
- visualComparison += '<div style="flex: 1;"><h4>النص المصدر:</h4><pre style="background-color: #f8f8f8; padding: 10px; border-radius: 4px; overflow-x: auto;">';
278
- for (let i = 0; i < maxLines; i++) {
279
- if (i < sourceLines.length) {
280
- visualComparison += `<div>${i+1}. ${sourceLines[i] || ''}</div>`;
281
- }
282
- }
283
- visualComparison += '</pre></div>';
284
-
285
- // عمود النص الهدف
286
- visualComparison += '<div style="flex: 1;"><h4>النص الهدف:</h4><pre style="background-color: #f8f8f8; padding: 10px; border-radius: 4px; overflow-x: auto;">';
287
- for (let i = 0; i < maxLines; i++) {
288
- if (i < targetLines.length) {
289
- visualComparison += `<div>${i+1}. ${targetLines[i] || ''}</div>`;
290
- }
291
- }
292
- visualComparison += '</pre></div>';
293
-
294
- visualComparison += '</div>';
295
-
296
- return formattedText + '<br><br>' + visualComparison;
297
  }
298
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  </body>
300
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="ar" dir="rtl">
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%; }
17
+ 50% { background-position: 100% 50%; }
18
+ 100% { background-position: 0% 50%; }
19
+ }
20
+ .animate-gradient {
21
+ background-size: 200% 200%;
22
+ animation: gradient 15s ease infinite;
23
+ }
24
+ .transition-all { transition: all 0.3s ease-in-out; }
25
+ .animate-scale { transition: transform 0.2s ease-in-out; }
26
+ .animate-scale:hover { transform: scale(1.02); }
27
+ .pulse-animation { animation: pulse 2s infinite; }
28
+ @keyframes pulse {
29
+ 0% { box-shadow: 0 0 0 0 rgba(156,39,176,0.4); }
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
+ .text-comparison { line-height: 1.8; white-space: pre-wrap; }
37
+ .highlight-number {
38
+ background-color: #FDE68A;
39
+ padding: 0 4px;
40
+ border-radius: 3px;
41
+ font-weight: bold;
42
+ }
43
+ .highlight-missing {
44
+ background-color: #BFDBFE;
45
+ padding: 0 4px;
46
+ border-radius: 3px;
47
+ font-style: italic;
48
+ }
49
+ .highlight-meaning {
50
+ background-color: #fecaca;
51
+ color: #B91C1C;
52
+ padding: 0 4px;
53
+ border-radius: 3px;
54
+ font-weight: bold;
55
+ }
56
+ /* ================================
57
+ تنسيق عرض السطور في المعاينة (من الكود الأول)
58
+ ================================= */
59
+ .split-view {
60
+ display: grid;
61
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
62
+ gap: 1rem;
63
+ }
64
+ .line-item {
65
+ display: flex;
66
+ align-items: flex-start;
67
+ margin-bottom: 0.5rem;
68
+ }
69
+ .line-number {
70
+ width: 30px;
71
+ font-weight: bold;
72
+ color: #4B5563;
73
+ flex-shrink: 0;
74
+ }
75
+ .line-text { flex: 1; }
76
+ /* ================================
77
+ تحسين تنسيق البطاقات والعناصر (من الكود الأول)
78
+ ================================= */
79
+ .card-hover {
80
+ transition: all 0.3s ease;
81
+ }
82
+ .card-hover:hover {
83
+ box-shadow: 0 10px 25px -5px rgba(156,39,176,0.1), 0 10px 10px -5px rgba(156,39,176,0.04);
84
+ transform: translateY(-2px);
85
+ }
86
+ /* ================================
87
+ إضافات من الكود الثاني للتنسيق المفصل للاختلافات
88
+ ================================= */
89
+ .diff-highlight {
90
+ display: inline;
91
+ padding: 2px 0;
92
+ }
93
+ .diff-added {
94
+ background-color: #c8e6c9;
95
+ text-decoration: none;
96
+ }
97
+ .diff-removed {
98
+ background-color: #ffcdd2;
99
+ text-decoration: line-through;
100
+ }
101
+ .diff-changed {
102
+ background-color: #fff9c4;
103
+ text-decoration: none;
104
+ }
105
+ /* تنسيق قسم مفتاح الـ API باستخدام Tailwind */
106
+ .api-key-input input {
107
+ width: 100%;
108
+ padding: 0.75rem;
109
+ border: 2px solid #ddd;
110
+ border-radius: 0.5rem;
111
+ outline: none;
112
+ transition: border-color 0.3s;
113
+ }
114
+ .api-key-input input:focus {
115
+ border-color: #6366F1;
116
+ }
117
+ </style>
118
  </head>
119
+ <body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
120
+ <div class="min-h-screen pb-12">
121
+ <!-- ============ رأس الصفحة ============ -->
122
+ <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">
123
+ <div class="max-w-6xl mx-auto px-4">
124
+ <h1 class="text-5xl font-bold text-center mb-4 animate-scale">نظام شركة موندو لينجوا - مراجعة النصوص</h1>
125
+ <p class="text-center text-xl text-blue-100 opacity-90">مقارنة وتحليل النصوص بدقة عالية</p>
126
+ </div>
127
+ </header>
128
+
129
+ <!-- ============ المحتوى الرئيسي ============ -->
130
+ <main class="max-w-6xl mx-auto px-4 space-y-8">
131
+ <!-- قسم مفتاح API -->
132
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale card-hover">
133
+ <div class="api-key-input">
134
+ <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
135
+ <i class="fas fa-key text-green-600 ml-2"></i> مفتاح API
136
+ </label>
137
+ <input type="text" id="apiKey" value="sk-21a46269cd8e449f8aeb0cc129c36c33" placeholder="أدخل مفتاح API هنا...">
138
  </div>
139
+ </div>
140
+
141
+ <!-- قسم رفع الملفات -->
142
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale card-hover">
143
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
144
+ <i class="fas fa-file-upload text-indigo-600 ml-2"></i> تحميل الملفات
145
+ </h2>
146
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
147
+ <!-- ملف السورس -->
148
+ <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">
149
+ <label class="cursor-pointer block">
150
+ <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
151
+ <i class="fas fa-file-upload text-5xl text-indigo-500 mb-4"></i>
152
+ <span class="text-lg text-indigo-600 group-hover:text-indigo-700">ملف السورس</span>
153
+ </label>
154
+ </div>
155
+ <!-- ملف التارجت -->
156
+ <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">
157
+ <label class="cursor-pointer block">
158
+ <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
159
+ <i class="fas fa-file-download text-5xl text-pink-500 mb-4"></i>
160
+ <span class="text-lg text-pink-600 group-hover:text-pink-700">ملف التارجت</span>
161
+ </label>
162
+ </div>
163
  </div>
164
+ <div id="processStatus" class="hidden mt-4">
165
+ <div class="flex items-center justify-center space-x-3 bg-indigo-100 rounded-xl p-4">
166
+ <div class="animate-spin h-8 w-8 border-4 border-indigo-600 rounded-full border-t-transparent"></div>
167
+ <span class="text-lg text-indigo-700">جارٍ معالجة الملف...</span>
168
+ </div>
169
  </div>
170
+ </div>
171
+
172
+ <!-- قسم إدخال النصوص يدويًا -->
173
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale card-hover">
174
+ <div class="space-y-6">
175
+ <!-- النص المصدر -->
176
+ <div class="group">
177
+ <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
178
+ <i class="fas fa-language text-indigo-600 ml-2"></i> النص المصدر
179
+ </label>
180
+ <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>
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-language text-pink-600 ml-2"></i> النص الهدف
186
+ </label>
187
+ <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>
188
+ </div>
189
  </div>
190
+ </div>
191
+
192
+ <!-- (يمكنك إضافة قسم المصادر الإضافية إن رغبت) -->
193
+
194
+ <!-- زر المقارنة / التحليل -->
195
+ <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">
196
+ <div class="flex items-center justify-center">
197
+ <i class="fas fa-sync-alt ml-2"></i> قارن النصوص
198
  </div>
199
+ </button>
200
+
201
+ <!-- شاشة عرض النتائج -->
202
+ <div id="resultSection" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale hidden card-hover">
203
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
204
+ <i class="fas fa-search text-green-600 ml-2"></i> نتائج التحليل والمقارنة
205
+ </h2>
206
+ <!-- هنا سيتم عرض الشرح التفصيلي مع مقارنة سطرية -->
207
+ <div id="comparisonResults" class="space-y-6"></div>
208
+ </div>
209
+ </main>
210
+ </div>
211
+
212
+ <!-- ================================
213
+ جافا سكريبت: الوظائف والمعالجة
214
+ ================================= -->
215
+ <script>
216
+ // إعدادات API الأساسية
217
+ const API_URL = 'https://api.deepseek.com/chat/completions';
218
+
219
+ /* =====================================
220
+ دوال مساعدة للتعامل مع النصوص (من الكود الأول)
221
+ ===================================== */
222
+ function countWords(text) {
223
+ return text.trim().split(/\s+/).filter(word => word !== "").length;
224
+ }
225
+ function escapeRegExp(string) {
226
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
227
+ }
228
+ function splitIntoLines(text) {
229
+ return text.split('\n').map((line, i) => `<div class="line-item"><span class="line-number">${i+1}:</span> <span class="line-text">${line}</span></div>`).join('');
230
+ }
231
+ function getLineNumber(text, substring) {
232
+ const index = text.indexOf(substring);
233
+ if (index === -1) return "غير محدد";
234
+ return text.substring(0, index).split("\n").length;
235
+ }
236
+
237
+ /* =====================================
238
+ دالة تنسيق النتيجة بالشكل المفصل (من الكود الثاني)
239
+ ===================================== */
240
+ function formatAnalysisResult(analysisText, sourceText, targetText) {
241
+ // استبدال بعض العبارات لتحديد الاختلافات
242
+ let formattedText = analysisText
243
+ .replace(/\n/g, '<br>')
244
+ .replace(/الأرقام المكتوبة بشكل خاطئ:|الأرقام غير الصحيحة:/gi, '<strong class="text-red-600">الأرقام المكتوبة بشكل خاطئ:</strong>')
245
+ .replace(/النصوص المفقودة:/gi, '<strong class="text-red-600">النصوص المفقودة:</strong>')
246
+ .replace(/النصوص الفاسدة:|النصوص غير المفهومة:/gi, '<strong class="text-red-600">النصوص الفاسدة:</strong>')
247
+ .replace(/النصوص المختلفة في المعنى:/gi, '<strong class="text-red-600">النصوص المختلفة في المعنى:</strong>')
248
+ .replace(/في النص المصدر: "(.*?)"/g, 'في النص المصدر: "<span class="diff-highlight diff-removed">$1</span>"')
249
+ .replace(/في النص الهدف: "(.*?)"/g, 'في النص الهدف: "<span class="diff-highlight diff-added">$1</span>"');
250
+
251
+ // مقارنة سطرية مرئية
252
+ const sourceLines = sourceText.split('\n');
253
+ const targetLines = targetText.split('\n');
254
+ const maxLines = Math.max(sourceLines.length, targetLines.length);
255
+
256
+ let visualComparison = '<h3 class="text-lg font-bold text-gray-700 mt-6 mb-3">المقارنة السطرية:</h3><div class="flex flex-col md:flex-row gap-6">';
257
+
258
+ // عمود النص المصدر
259
+ visualComparison += '<div class="flex-1"><h4 class="font-bold text-indigo-600 mb-2">النص المصدر:</h4><div class="bg-indigo-50 p-4 rounded-lg border border-indigo-100 overflow-x-auto">';
260
+ for (let i = 0; i < maxLines; i++) {
261
+ if(i < sourceLines.length) {
262
+ visualComparison += `<div>${i+1}. ${sourceLines[i]}</div>`;
263
+ }
264
+ }
265
+ visualComparison += '</div></div>';
266
+
267
+ // عمود النص الهدف
268
+ visualComparison += '<div class="flex-1"><h4 class="font-bold text-pink-600 mb-2">النص الهدف:</h4><div class="bg-pink-50 p-4 rounded-lg border border-pink-100 overflow-x-auto">';
269
+ for (let i = 0; i < maxLines; i++) {
270
+ if(i < targetLines.length) {
271
+ visualComparison += `<div>${i+1}. ${targetLines[i]}</div>`;
272
+ }
273
+ }
274
+ visualComparison += '</div></div>';
275
+
276
+ visualComparison += '</div>';
277
+
278
+ return formattedText + '<br><br>' + visualComparison;
279
+ }
280
+
281
+ /* =====================================
282
+ دالة معالجة الملفات (PDF و DOCX) - من الكود الأول
283
+ ===================================== */
284
+ async function processFile(file) {
285
+ let text = "";
286
+ if (file.type === 'application/pdf') {
287
+ const form = new FormData();
288
+ form.append('image', file);
289
+ const response = await fetch('https://demo.api4ai.cloud/ocr/v1/results', {
290
+ method: 'POST',
291
+ body: form,
292
+ headers: { 'A4A-CLIENT-APP-ID': 'sample' }
293
+ });
294
+ const data = await response.json();
295
+ text = data.results[0].entities[0].objects[0].entities[0].text;
296
+ } else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
297
+ const arrayBuffer = await file.arrayBuffer();
298
+ const result = await mammoth.extractRawText({ arrayBuffer });
299
+ text = result.value;
300
+ } else {
301
+ throw new Error('نوع الملف غير مدعوم');
302
+ }
303
+ return text;
304
+ }
305
+
306
+ /* =====================================
307
+ دوال رفع الملفات وإدخال النصوص - من الكود الأول
308
+ ===================================== */
309
+ document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
310
+ const file = event.target.files[0];
311
+ if (!file) return;
312
+ document.getElementById('processStatus').classList.remove('hidden');
313
+ try {
314
+ const text = await processFile(file);
315
+ document.getElementById('sourceText').value = text;
316
+ } catch (error) {
317
+ console.error('Error processing source file:', error);
318
+ alert('خطأ في معالجة ملف السورس');
319
+ } finally {
320
+ document.getElementById('processStatus').classList.add('hidden');
321
+ }
322
+ });
323
+ document.getElementById('targetFile')?.addEventListener('change', async (event) => {
324
+ const file = event.target.files[0];
325
+ if (!file) return;
326
+ document.getElementById('processStatus').classList.remove('hidden');
327
+ try {
328
+ const text = await processFile(file);
329
+ document.getElementById('targetText').value = text;
330
+ } catch (error) {
331
+ console.error('Error processing target file:', error);
332
+ alert('خطأ في معالجة ملف التارجت');
333
+ } finally {
334
+ document.getElementById('processStatus').classList.add('hidden');
335
+ }
336
+ });
337
+
338
+ /* =====================================
339
+ دالة التعامل مع حدث النقر على زر المقارنة
340
+ ===================================== */
341
+ document.getElementById('submitBtn').addEventListener('click', async () => {
342
+ const sourceText = document.getElementById('sourceText').value.trim();
343
+ const targetText = document.getElementById('targetText').value.trim();
344
+ const apiKey = document.getElementById('apiKey').value.trim();
345
+ const resultsContainer = document.getElementById('comparisonResults');
346
+ const resultSection = document.getElementById('resultSection');
347
 
348
+ resultsContainer.innerHTML = '';
349
+
350
+ if (!sourceText || !targetText) {
351
+ alert('الرجاء إدخال كلا النصين المصدر والهدف');
352
+ return;
353
+ }
354
+ if (!apiKey) {
355
+ alert('الرجاء إدخال مفتاح API صالح');
356
+ return;
357
+ }
358
+
359
+ // مقارنة عدد الكلمات وتنبيه إن وجد اختلاف (اختياري)
360
+ const sourceWordCount = countWords(sourceText);
361
+ const targetWordCount = countWords(targetText);
362
+ if (sourceWordCount !== targetWordCount) {
363
+ resultsContainer.innerHTML += `<div class="p-4 rounded-xl bg-yellow-50 text-yellow-700 mb-4"><i class="fas fa-info-circle ml-2"></i> عدد كلمات النص المصدر (${sourceWordCount}) يختلف عن النص الهدف (${targetWordCount}).</div>`;
364
+ }
365
+
366
+ // عرض مؤشر التقدم
367
+ resultsContainer.innerHTML += `<div id="progressIndicator" class="bg-indigo-100 p-4 rounded-xl mb-4 flex items-center justify-center">
368
+ <div class="animate-spin h-8 w-8 border-4 border-indigo-600 rounded-full border-t-transparent mr-3"></div>
369
+ <span class="text-indigo-700 text-lg">جارٍ التحليل...</span>
370
+ </div>`;
371
+
372
+ // بناء prompt باستخدام نصوص الكلا المصدر والهدف (باستخدام نص الكود الثاني)
373
+ const prompt = `
 
 
 
 
 
374
  قارن بين النص المصدر والنص الهدف وحدد الاختلافات بينهما، بما في ذلك:
375
  1. الأرقام المكتوبة بشكل خاطئ
376
  2. النصوص المفقودة
377
  3. النصوص الفاسدة أو غير المفهومة
378
  4. النصوص المختلفة في المعنى
379
 
380
+ قدم تحليلاً مفصلاً للاختلافات وتصنيفها حسب نوع الخطأ.
 
381
 
382
  النص المصدر:
383
  ${sourceText}
384
 
385
  النص الهدف:
386
  ${targetText}
387
+ `;
388
+
389
+ try {
390
+ const payload = {
391
+ model: 'deepseek-reasoner',
392
+ messages: [
393
+ { role: 'system', content: 'أنت مساعد متخصص في مراجعة النصوص وتحديد الاختلافات بينها بدقة عالية.' },
394
+ { role: 'user', content: prompt }
395
+ ],
396
+ temperature: 0.3,
397
+ max_tokens: 2048,
398
+ stream: false
399
+ };
400
+
401
+ const response = await fetch(API_URL, {
402
+ method: 'POST',
403
+ headers: {
404
+ 'Content-Type': 'application/json',
405
+ 'Authorization': 'Bearer ' + apiKey
406
+ },
407
+ body: JSON.stringify(payload)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  });
409
 
410
+ if (!response.ok) {
411
+ throw new Error('خطأ في الاتصال بالـ API: ' + response.statusText);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  }
413
+
414
+ const data = await response.json();
415
+ const analysisResult = data.choices[0].message.content.trim();
416
+
417
+ // إزالة مؤشر التقدم
418
+ const progressIndicator = document.getElementById('progressIndicator');
419
+ if (progressIndicator) progressIndicator.remove();
420
+
421
+ // عرض النتيجة باستخدام دالة التنسيق (من الكود الثاني)
422
+ const formattedResult = formatAnalysisResult(analysisResult, sourceText, targetText);
423
+ resultsContainer.innerHTML += formattedResult;
424
+ resultSection.classList.remove('hidden');
425
+ } catch (error) {
426
+ resultsContainer.innerHTML = '';
427
+ alert('حدث خطأ في التحليل: ' + error.message);
428
+ console.error('Error:', error);
429
+ }
430
+ });
431
+ </script>
432
  </body>
433
  </html>