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

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +194 -188
index.html CHANGED
@@ -189,8 +189,6 @@
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">
@@ -213,164 +211,170 @@
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. النصوص المفقودة
@@ -384,48 +388,50 @@ ${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>
 
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">
 
211
  جافا سكريبت: الوظائف والمعالجة
212
  ================================= -->
213
  <script>
214
+ document.addEventListener('DOMContentLoaded', function() {
215
+ // إعدادات API الأساسية
216
+ const API_URL = 'https://api.deepseek.com/chat/completions';
217
 
218
+ /* =====================================
219
+ دوال مساعدة للتعامل مع النصوص (من الكود الأول)
220
+ ===================================== */
221
+ function countWords(text) {
222
+ return text.trim().split(/\s+/).filter(word => word !== "").length;
223
+ }
224
+ function escapeRegExp(string) {
225
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
226
+ }
227
+ function splitIntoLines(text) {
228
+ 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('');
229
+ }
230
+ function getLineNumber(text, substring) {
231
+ const index = text.indexOf(substring);
232
+ if (index === -1) return "غير محدد";
233
+ return text.substring(0, index).split("\n").length;
234
+ }
235
 
236
+ /* =====================================
237
+ دالة تنسيق النتيجة بالشكل المفصل (من الكود الثاني)
238
+ ===================================== */
239
+ function formatAnalysisResult(analysisText, sourceText, targetText) {
240
+ let formattedText = analysisText
241
+ .replace(/\n/g, '<br>')
242
+ .replace(/الأرقام المكتوبة بشكل خاطئ:|الأرقام غير الصحيحة:/gi, '<strong class="text-red-600">الأرقام المكتوبة بشكل خاطئ:</strong>')
243
+ .replace(/النصوص المفقودة:/gi, '<strong class="text-red-600">النصوص المفقودة:</strong>')
244
+ .replace(/النصوص الفاسدة:|النصوص غير المفهومة:/gi, '<strong class="text-red-600">النصوص الفاسدة:</strong>')
245
+ .replace(/النصوص المختلفة في المعنى:/gi, '<strong class="text-red-600">النصوص المختلفة في المعنى:</strong>')
246
+ .replace(/في النص المصدر: "(.*?)"/g, 'في النص المصدر: "<span class="diff-highlight diff-removed">$1</span>"')
247
+ .replace(/في النص الهدف: "(.*?)"/g, 'في النص الهدف: "<span class="diff-highlight diff-added">$1</span>"');
248
+
249
+ // مقارنة سطرية مرئية
250
+ const sourceLines = sourceText.split('\n');
251
+ const targetLines = targetText.split('\n');
252
+ const maxLines = Math.max(sourceLines.length, targetLines.length);
253
+
254
+ 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">';
255
+
256
+ 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">';
257
+ for (let i = 0; i < maxLines; i++) {
258
+ if(i < sourceLines.length) {
259
+ visualComparison += `<div>${i+1}. ${sourceLines[i]}</div>`;
260
+ }
 
261
  }
262
+ visualComparison += '</div></div>';
263
+
264
+ 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">';
265
+ for (let i = 0; i < maxLines; i++) {
266
+ if(i < targetLines.length) {
267
+ visualComparison += `<div>${i+1}. ${targetLines[i]}</div>`;
268
+ }
 
269
  }
270
+ visualComparison += '</div></div>';
271
+
272
+ visualComparison += '</div>';
273
+
274
+ return formattedText + '<br><br>' + visualComparison;
275
  }
 
 
 
 
 
 
276
 
277
+ /* =====================================
278
+ دالة معالجة الملفات (PDF و DOCX) - من الكود الأول
279
+ ===================================== */
280
+ async function processFile(file) {
281
+ let text = "";
282
+ if (file.type === 'application/pdf') {
283
+ const form = new FormData();
284
+ form.append('image', file);
285
+ const response = await fetch('https://demo.api4ai.cloud/ocr/v1/results', {
286
+ method: 'POST',
287
+ body: form,
288
+ headers: { 'A4A-CLIENT-APP-ID': 'sample' }
289
+ });
290
+ const data = await response.json();
291
+ text = data.results[0].entities[0].objects[0].entities[0].text;
292
+ } else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
293
+ const arrayBuffer = await file.arrayBuffer();
294
+ const result = await mammoth.extractRawText({ arrayBuffer });
295
+ text = result.value;
296
+ } else {
297
+ throw new Error('نوع الملف غير مدعوم');
298
+ }
299
+ return text;
300
  }
 
 
301
 
302
+ /* =====================================
303
+ ربط أحداث رفع الملفات (من الكود الأول)
304
+ ===================================== */
305
+ const sourceFileEl = document.getElementById('sourceFile');
306
+ if (sourceFileEl) {
307
+ sourceFileEl.addEventListener('change', async (event) => {
308
+ const file = event.target.files[0];
309
+ if (!file) return;
310
+ document.getElementById('processStatus').classList.remove('hidden');
311
+ try {
312
+ const text = await processFile(file);
313
+ document.getElementById('sourceText').value = text;
314
+ } catch (error) {
315
+ console.error('Error processing source file:', error);
316
+ alert('خطأ في معالجة ملف السورس');
317
+ } finally {
318
+ document.getElementById('processStatus').classList.add('hidden');
319
+ }
320
+ });
321
  }
322
+ const targetFileEl = document.getElementById('targetFile');
323
+ if (targetFileEl) {
324
+ targetFileEl.addEventListener('change', async (event) => {
325
+ const file = event.target.files[0];
326
+ if (!file) return;
327
+ document.getElementById('processStatus').classList.remove('hidden');
328
+ try {
329
+ const text = await processFile(file);
330
+ document.getElementById('targetText').value = text;
331
+ } catch (error) {
332
+ console.error('Error processing target file:', error);
333
+ alert('خطأ في معالجة ملف التارجت');
334
+ } finally {
335
+ document.getElementById('processStatus').classList.add('hidden');
336
+ }
337
+ });
338
  }
 
339
 
340
+ /* =====================================
341
+ حدث النقر على زر المقارنة / التحليل
342
+ ===================================== */
343
+ const submitBtn = document.getElementById('submitBtn');
344
+ if (submitBtn) {
345
+ submitBtn.addEventListener('click', async () => {
346
+ const sourceText = document.getElementById('sourceText').value.trim();
347
+ const targetText = document.getElementById('targetText').value.trim();
348
+ const apiKey = document.getElementById('apiKey').value.trim();
349
+ const resultsContainer = document.getElementById('comparisonResults');
350
+ const resultSection = document.getElementById('resultSection');
351
 
352
+ resultsContainer.innerHTML = '';
353
 
354
+ if (!sourceText || !targetText) {
355
+ alert('الرجاء إدخال كلا النصين المصدر والهدف');
356
+ return;
357
+ }
358
+ if (!apiKey) {
359
+ alert('الرجاء إدخال مفتاح API صالح');
360
+ return;
361
+ }
362
+
363
+ // مقارنة عدد الكلمات وتنبيه إن وجد اختلاف (اختياري)
364
+ const sourceWordCount = countWords(sourceText);
365
+ const targetWordCount = countWords(targetText);
366
+ if (sourceWordCount !== targetWordCount) {
367
+ 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>`;
368
+ }
369
+
370
+ // عرض مؤشر التقدم
371
+ resultsContainer.innerHTML += `<div id="progressIndicator" class="bg-indigo-100 p-4 rounded-xl mb-4 flex items-center justify-center">
372
+ <div class="animate-spin h-8 w-8 border-4 border-indigo-600 rounded-full border-t-transparent mr-3"></div>
373
+ <span class="text-indigo-700 text-lg">جارٍ التحليل...</span>
374
+ </div>`;
375
+
376
+ // بناء prompt باستخدام نصوص المصدر والهدف
377
+ const prompt = `
378
  قارن بين النص المصدر والنص الهدف وحدد الاختلافات بينهما، بما في ذلك:
379
  1. الأرقام المكتوبة بشكل خاطئ
380
  2. النصوص المفقودة
 
388
 
389
  النص الهدف:
390
  ${targetText}
391
+ `;
392
+
393
+ try {
394
+ const payload = {
395
+ model: 'deepseek-reasoner',
396
+ messages: [
397
+ { role: 'system', content: 'أنت مساعد متخصص في مراجعة النصوص وتحديد الاختلافات بينها بدقة عالية.' },
398
+ { role: 'user', content: prompt }
399
+ ],
400
+ temperature: 0.3,
401
+ max_tokens: 2048,
402
+ stream: false
403
+ };
404
+
405
+ const response = await fetch(API_URL, {
406
+ method: 'POST',
407
+ headers: {
408
+ 'Content-Type': 'application/json',
409
+ 'Authorization': 'Bearer ' + apiKey
410
+ },
411
+ body: JSON.stringify(payload)
412
+ });
413
+
414
+ if (!response.ok) {
415
+ throw new Error('خطأ في الاتصال بالـ API: ' + response.statusText);
416
+ }
417
+
418
+ const data = await response.json();
419
+ const analysisResult = data.choices[0].message.content.trim();
420
+
421
+ // إزالة مؤشر التقدم
422
+ const progressIndicator = document.getElementById('progressIndicator');
423
+ if (progressIndicator) progressIndicator.remove();
424
+
425
+ // عرض النتيجة باستخدام دالة التنسيق
426
+ const formattedResult = formatAnalysisResult(analysisResult, sourceText, targetText);
427
+ resultsContainer.innerHTML += formattedResult;
428
+ resultSection.classList.remove('hidden');
429
+ } catch (error) {
430
+ resultsContainer.innerHTML = '';
431
+ alert('حدث خطأ في التحليل: ' + error.message);
432
+ console.error('Error:', error);
433
+ }
434
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  }
436
  });
437
  </script>