/** * @fileoverview * @module utils/linguistic-engine * @description */ (global => { 'use strict'; const HOMOGLYPHS_DB = Object.freeze({ 'ا': Object.freeze(['\u0627', '\u0430', '\u05D0', '\u1D00']), 'أ': Object.freeze(['\u0623', '\u0627', '\u0430']), 'إ': Object.freeze(['\u0625', '\u0627', '\u05D0']), 'آ': Object.freeze(['\u0622', '\u0627']), 'ب': Object.freeze(['\u0628', '\u0432']), 'ت': Object.freeze(['\u062A']), 'ث': Object.freeze(['\u062B']), 'ج': Object.freeze(['\u062C']), 'ح': Object.freeze(['\u062D', '\u043D']), 'خ': Object.freeze(['\u062E', '\u0445', '\u03C7']), 'د': Object.freeze(['\u062F', '\u05D3', '\u0434']), 'ذ': Object.freeze(['\u0630']), 'ر': Object.freeze(['\u0631', '\u0440', '\u03C1']), 'ز': Object.freeze(['\u0632']), 'س': Object.freeze(['\u0633', '\u0441']), 'ش': Object.freeze(['\u0634']), 'ص': Object.freeze(['\u0635']), 'ض': Object.freeze(['\u0636']), 'ط': Object.freeze(['\u0637']), 'ظ': Object.freeze(['\u0638']), 'ع': Object.freeze(['\u0639']), 'غ': Object.freeze(['\u063A']), 'ف': Object.freeze(['\u0641', '\u03C6']), 'ق': Object.freeze(['\u0642']), 'ك': Object.freeze(['\u0643', '\u03BA', '\u043A']), 'ل': Object.freeze(['\u0644']), 'م': Object.freeze(['\u0645', '\u03BC', '\u043C']), 'ن': Object.freeze(['\u0646']), 'ه': Object.freeze(['\u0647', '\u0435', '\u03BF', '\u05E5']), 'ة': Object.freeze(['\u0629']), 'و': Object.freeze(['\u0648', '\u03BF', '\u043E']), 'ؤ': Object.freeze(['\u0624']), 'ي': Object.freeze(['\u064A', '\u0456', '\u03B9']), 'ى': Object.freeze(['\u0649']), 'ئ': Object.freeze(['\u0626']), 'a': Object.freeze(['a', '\u0430', '\u03B1', '\uFF41']), 'b': Object.freeze(['b', '\uFF42', '\u1D47']), 'c': Object.freeze(['c', '\u0441', '\u03F2', '\uFF43']), 'd': Object.freeze(['d', '\uFF44', '\u2146']), 'e': Object.freeze(['e', '\u0435', '\u03B5', '\uFF45']), 'f': Object.freeze(['f', '\uFF46', '\u1DA0']), 'g': Object.freeze(['g', '\uFF47', '\u0261']), 'h': Object.freeze(['h', '\u04BB', '\uFF48']), 'i': Object.freeze(['i', '\u0456', '\u03B9', '\uFF49', '\u0131']), 'j': Object.freeze(['j', '\u0452', '\u03F2', '\uFF4A']), 'k': Object.freeze(['k', '\u043A', '\u03BA', '\uFF4B']), 'l': Object.freeze(['l', '\u04CF', '\uFF4C', '\u2113']), 'm': Object.freeze(['m', '\u043C', '\u03BC', '\uFF4D']), 'n': Object.freeze(['n', '\uFF4E', '\u0272']), 'o': Object.freeze(['o', '\u043E', '\u03BF', '\uFF4F', '\u0585']), 'p': Object.freeze(['p', '\u0440', '\u03C1', '\uFF50']), 'q': Object.freeze(['q', '\uFF51', '\u024A']), 'r': Object.freeze(['r', '\u027E', '\uFF52']), 's': Object.freeze(['s', '\u0455', '\uFF53', '\u015F']), 't': Object.freeze(['t', '\uFF54', '\u0163']), 'u': Object.freeze(['u', '\u03C5', '\u0443', '\uFF55']), 'v': Object.freeze(['v', '\u03BD', '\uFF56', '\u1D1B']), 'w': Object.freeze(['w', '\uFF57', '\u027F']), 'x': Object.freeze(['x', '\u0445', '\u03C7', '\uFF58']), 'y': Object.freeze(['y', '\u0443', '\u03C5', '\uFF59']), 'z': Object.freeze(['z', '\uFF5A', '\u0225']), 'A': Object.freeze(['A', '\u0391', '\u0410', '\uFF21']), 'B': Object.freeze(['B', '\u0392', '\u0412', '\uFF22']), 'C': Object.freeze(['C', '\u03F9', '\u0421', '\uFF23']), 'D': Object.freeze(['D', '\uFF24', '\u0501']), 'E': Object.freeze(['E', '\u0395', '\u0415', '\uFF22']), 'F': Object.freeze(['F', '\uFF26', '\u1E1E']), 'G': Object.freeze(['G', '\uFF27', '\u0192']), 'H': Object.freeze(['H', '\u0397', '\u041D', '\uFF28']), 'I': Object.freeze(['I', '\u0399', '\u0406', '\uFF29']), 'J': Object.freeze(['J', '\u0408', '\uFF2A']), 'K': Object.freeze(['K', '\u039A', '\u041A', '\uFF2B']), 'L': Object.freeze(['L', '\uFF2C', '\u2112']), 'M': Object.freeze(['M', '\u039C', '\u041C', '\uFF2D']), 'N': Object.freeze(['N', '\u039D', '\uFF2E', '\u019D']), 'O': Object.freeze(['O', '\u039F', '\u041E', '\uFF2F']), 'P': Object.freeze(['P', '\u03A1', '\u0420', '\uFF30']), 'Q': Object.freeze(['Q', '\uFF31', '\u024A']), 'R': Object.freeze(['R', '\uFF32', '\u1154']), 'S': Object.freeze(['S', '\uFF33', '\u1E60']), 'T': Object.freeze(['T', '\u03A4', '\u0422', '\uFF34']), 'U': Object.freeze(['U', '\u03A5', '\u04AE', '\uFF35']), 'V': Object.freeze(['V', '\u039B', '\uFF36']), 'W': Object.freeze(['W', '\uFF37', '\u019C']), 'X': Object.freeze(['X', '\u03A7', '\u0425', '\uFF38']), 'Y': Object.freeze(['Y', '\u03A5', '\u04AE', '\uFF39']), 'Z': Object.freeze(['Z', '\uFF3A', '\u0124']) }); const ARABIC_SYNONYMS_THESAURUS = Object.freeze({ "بيع": Object.freeze(["تسويق", "تمليك", "عرض خاص للبيع", "إتاحة للتمليك", "التصرف بالبيع"]), "للبيع": Object.freeze(["للتمليك", "متاح للاقتناء", "فرصة نادرة للشراء", "معروض للتمليك", "جاهز للاستلام فورا"]), "شراء": Object.freeze(["اقتناء", "امتلاك", "الحصول على", "الاستحواذ على", "حجز"]), "اشتر": Object.freeze(["اقتني", "احجز الآن", "احصل على", "سارع بامتلاك", "تملّك فورا"]), "بيع سريع": Object.freeze(["بيع فوري عاجل", "تصفية عاجلة", "فرصة استثمارية سريعة", "تصفية نهائية"]), "سعر": Object.freeze(["ثمن البيع", "قيمة استثمارية", "تكلفة مالية", "مبلغ محدد", "قيمة إجمالية"]), "الأسعار": Object.freeze(["القيم المالية", "التكاليف الإجمالية", "الأسعار المطروحة حالياً"]), "رخيص": Object.freeze(["اقتصادي وموفر", "بسعر لقطة لا يتكرر", "تكلفة تنافسية مخفضة", "قيمة مغرية جداً"]), "غالي": Object.freeze(["فاخر وراقي", "عالي القيمة الاستثمارية", "متميز ونادر"]), "خصم": Object.freeze(["تخفيض فوري", "وفر مالي حصري", "عرض تخفيض خاص", "تنزيل مؤقت بالسعر"]), "خصومات": Object.freeze(["تخفيضات هائلة", "عروض خصم كبرى", "تنزيلات ترويجية حصرية", "أسعار مخفضة جداً"]), "تخفيض": Object.freeze(["خصم مالي", "تنزيل إضافي", "تقليل مباشر للتكلفة"]), "عرض": Object.freeze(["فرصة استثمارية صفقة", "صفقة ممتازة", "إعلان ترويجي مميز", "عرض حصري مؤقت"]), "عروض": Object.freeze(["فرص ذهبية", "صفقات لا تعوض", "مهرجان تخفيضات حصري", "عروض ممتازة جديدة"]), "شقة": Object.freeze(["وحدة سكنية راقية", "منزل سكني", "مسكن مستقل", "عقار سكني متميز"]), "شقق": Object.freeze(["وحدات سكنية متنوعة", "عقارات سكنية متميزة", "منازل ممتازة"]), "فيلا": Object.freeze(["قصر مستقل", "فيلّا فاخرة", "منزل مستقل فاخر", "وحدة سكنية مستقلة"]), "فلل": Object.freeze(["قصور متميزة", "فيلات مستقلة فاخرة", "وحدات سكنية فاخرة مستقلة"]), "دوبلكس": Object.freeze(["وحدة دوبلكس مستقلة", "شقة طابقين فاخرة"]), "بنتهاوس": Object.freeze(["شقة علوية بنتهاوس", "وحدة سكنية بحديقة علوية فاخرة"]), "استوديو": Object.freeze(["استوديو مجهز بالكامل", "شقة استوديو أنيقة"]), "عقار": Object.freeze(["وحدة استثمارية", "ملكية عقارية ممتازة", "ممتلكات فاخرة"]), "عقارات": Object.freeze(["مشاريع عقارية كبرى", "وحدات وممتلكات متميزة", "محفظة عقارية فاخرة"]), "أرض": Object.freeze(["قطعة أرض متميزة", "مساحة أرض صالحة للبناء فورا"]), "محل": Object.freeze(["وحدة تجارية متميزة", "متجر تجاري جاهز للتشغيل"]), "مكتب": Object.freeze(["مقر إداري مجهز", "وحدة إدارية ممتازة للشركات"]), "إيجار": Object.freeze(["استئجار مؤقت", "تأجير دوري", "إيجار شهري"]), "للإيجار": Object.freeze(["للايجار الفوري", "متاح للاستئجار", "جاهز للتأجير الفوري", "للاستثمار الإيجاري"]), "مؤجر": Object.freeze(["مستأجر حالي", "تم تأجيره بالكامل"]), "ممتاز": Object.freeze(["استثنائي رائع", "فاخر للغاية", "راقي ومميز جداً", "عالي الجودة والكفاءة"]), "رائع": Object.freeze(["مذهل وجذاب", "استثنائي غير مسبوق", "خيالي وساحر", "من الدرجة الأولى"]), "جيد": Object.freeze(["مناسب تماماً", "بحالة جيدة جداً", "مقبول ومطابق للمواصفات"]), "فاخر": Object.freeze(["سوبر لوكس راقي", "الترا لوكس فاخر", "متميز ونخبوي"]), "جديد": Object.freeze(["حديث كلياً", "أول استخدام لم يستعمل", "جديد تماماً بأوراق المصنع"]), "قديم": Object.freeze(["مستعمل بحالة ممتازة", "كلاسيكي كسر زيرو"]), "تواصل": Object.freeze(["راسلنا الآن مباشرة", "استفسر من فريق العمل", "كلمنا فورا", "تحدث مع المبيعات"]), "اتصل": Object.freeze(["تواصل معنا", "راسلنا بالاتصال المباشر", "تحدث معنا هاتفياً فورا"]), "واتساب": Object.freeze(["الواتساب المباشر", "عبر شات واتساب", "WhatsApp Chat فوري"]), "رقم": Object.freeze(["رقم الهاتف الموثق", "وسيلة الاتصال المباشرة", "الخط الساخن للخدمة"]), "فرصة": Object.freeze(["عرض لقطة استثنائي", "صفقة العمر الممتازة", "فرصة ذهبية نادرة", "مناسبة ممتازة"]), "فرصة ذهبية": Object.freeze(["صفقة استثمارية لا تتكرر", "عرض العمر الحصري"]), "حصري": Object.freeze(["حصرياً وبشكل خاص", "لفترة محدودة جداً للرواد", "إعلان مميز مخصص"]), "لفترة محدودة": Object.freeze(["لفترة وجيزة جداً", "عرض مؤقت ينتهي قريباً", "فرصة عاجلة تسري لأيام"]), "كاش": Object.freeze(["نقداً فوري", "دفع كاش نقدي كامل"]), "تقسيط": Object.freeze(["أقساط مرنة مريحة", "دفعات شهرية ميسرة", "أنظمة سداد وتقسيط"]), "بدون مقدم": Object.freeze(["بصفر مقدم تعاقد", "بدون دفعة أولى مقدمة", "تسهيلات بدون دفعة حجز"]), "تمويل": Object.freeze(["تسهيلات تمويلية وسداد", "تسهيلات دفع طويلة المدى"]), "مدينة": Object.freeze(["منطقة سكنية متكاملة", "حي راقي وهادئ", "مجمع سكني مغلق متميز"]), "موقع": Object.freeze(["لوكيشن مميز جداً", "عنوان جغرافي استراتيجي", "مقر حيوي للغاية"]), "قريب": Object.freeze(["على بعد خطوات بسيطة", "بالقرب الشديد من الخدمات", "بجوار المعالم الرئيسية"]), "أمام": Object.freeze(["مقابل ومواجه مباشرة لـ", "بإطلالة أمامية على"]), "داخل": Object.freeze(["في قلب منطقة", "ضمن نطاق أرقى مجمعات"]), "مساحة": Object.freeze(["مساحة إجمالية ممتازة", "مقاس هندسي متسع"]), "غرفة": Object.freeze(["حجرة مجهزة", "غرفة نوم واسعة"]), "غرف": Object.freeze(["حجرات متسعة", "غرف نوم مستقلة"]), "حمام": Object.freeze(["دورة مياه مجهزة بالكامل", "حمام راقي"]), "مطبخ": Object.freeze(["مطبخ أمريكي متكامل", "مطبخ عصري حديث"]), "بلكونة": Object.freeze(["شرفة بإطلالة مفتوحة", "بلكونة واسعة ذات رؤية متميزة"]), "حديقة": Object.freeze(["مساحة لاندسكيب خضراء", "حديقة خاصة مستقلة"]), "روف": Object.freeze(["روف علوي واسع ومستقل", "شقة روف علوية متميزة"]), "تشطيب": Object.freeze(["مستوى تشطيبات راقي", "إنهاءات هندسية فائقة الدقة"]), "فيو": Object.freeze(["منظر بانورامي مفتوح", "إطلالة ساحرة مباشرة"]), "تشطيب سوبر لوكس": Object.freeze(["تشطيب الترا سوبر لوكس فاخر", "مستوى تشطيبات راقي ونخبوية", "جاهز للسكن الفوري الفاخر"]) }); /** * @param {string} text * @param {number} density * @returns {string} */ function injectZeroWidthSpaces(text, density = 0.25) { if (!text) return text; const words = text.split(/(\s+)/); const processedWords = words.map(word => { if (/^\s+$/.test(word) || word.length <= 3) return word; if (Math.random() < density) { const chars = []; for (let i = 0; i < word.length; i++) { chars.push(word[i]); if (i < word.length - 1 && Math.random() < 0.35) { chars.push(Math.random() > 0.5 ? '\u200C' : '\u200B'); } } return chars.join(''); } return word; }); return processedWords.join(''); } /** * @param {string} text * @param {number} rate * @returns {string} */ function applyUnicodeHomoglyphs(text, rate = 0.20) { if (!text) return text; let result = ""; for (let i = 0; i < text.length; i++) { const char = text[i]; if (HOMOGLYPHS_DB[char] && Math.random() < rate) { const options = HOMOGLYPHS_DB[char]; const randomIndex = Math.floor(Math.random() * options.length); result += options[randomIndex]; } else { result += char; } } return result; } /** * إعادة الصياغة التلقائية للكلمات باستخدام معجم المترادفات * @param {string} text * @param {number} substitutionStrength - شدة الاستبدال * @returns {string} */ function autoParaphraseArabicText(text, substitutionStrength = 0.40) { if (!text) return text; let processedText = text; const keys = Object.keys(ARABIC_SYNONYMS_THESAURUS).sort((a, b) => b.length - a.length); keys.forEach(key => { if (Math.random() < substitutionStrength) { const regex = new RegExp(`(?<=^|\\s|\\p{P})${key}(?=$|\\s|\\p{P})`, 'gu'); if (regex.test(processedText)) { const synonyms = ARABIC_SYNONYMS_THESAURUS[key]; const randomSynonym = synonyms[Math.floor(Math.random() * synonyms.length)]; processedText = processedText.replace(regex, randomSynonym); } } }); return processedText; } /** * @param {Blob} imageBlob * @returns {Promise} */ async function stripExifAndObfuscateMedia(imageBlob) { if (!(imageBlob instanceof Blob)) return imageBlob; try { const arrayBuffer = await imageBlob.arrayBuffer(); const view = new DataView(arrayBuffer); if (view.getUint16(0) !== 0xFFD8) { return imageBlob; } const cleanSegments = []; let offset = 2; cleanSegments.push(arrayBuffer.slice(0, 2)); const length = arrayBuffer.byteLength; while (offset < length) { if (offset + 2 > length) break; const marker = view.getUint16(offset); if (marker >= 0xFFE1 && marker <= 0xFFEF) { const segmentLength = view.getUint16(offset + 2); offset += segmentLength + 2; continue; } if (marker === 0xFFDA) { cleanSegments.push(arrayBuffer.slice(offset)); break; } const segmentLength = view.getUint16(offset + 2); cleanSegments.push(arrayBuffer.slice(offset, offset + segmentLength + 2)); offset += segmentLength + 2; } const cleanedBlob = new Blob(cleanSegments, { type: imageBlob.type || 'image/jpeg' }); return await injectInvisibleImageNoise(cleanedBlob); } catch (err) { console.error("[Fritree Shield Obfuscator] EXIF stripping failed:", err); return imageBlob; } } /** * @param {Blob} imageBlob * @returns {Promise} */ function injectInvisibleImageNoise(imageBlob) { return new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(imageBlob); reader.onload = (event) => { const img = new Image(); img.src = event.target.result; img.onload = () => { const canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); if (ctx) { ctx.drawImage(img, 0, 0); const pixel = ctx.getImageData(img.width - 1, img.height - 1, 1, 1); pixel.data[0] = (pixel.data[0] + (Math.random() > 0.5 ? 1 : -1) + 256) % 256; pixel.data[1] = (pixel.data[1] + (Math.random() > 0.5 ? 1 : -1) + 256) % 256; pixel.data[2] = (pixel.data[2] + (Math.random() > 0.5 ? 1 : -1) + 256) % 256; ctx.putImageData(pixel, img.width - 1, img.height - 1); canvas.toBlob((obfuscatedBlob) => { resolve(obfuscatedBlob || imageBlob); }, 'image/jpeg', 0.85); } else { resolve(imageBlob); } }; img.onerror = () => resolve(imageBlob); }; reader.onerror = () => resolve(imageBlob); }); } /** * @param {string} rawText * @param {Object} config * @returns {Promise} */ async function processTextStealthMasking(rawText, config = {}) { if (!rawText) return rawText; let maskedText = rawText; const paraphraseStrength = config.synonymStrength !== undefined ? config.synonymStrength : 0.40; const homoglyphStrength = config.homoglyphStrength !== undefined ? config.homoglyphStrength : 0.20; const zwspDensity = config.zwspDensity !== undefined ? config.zwspDensity : 0.25; if (paraphraseStrength > 0) { maskedText = autoParaphraseArabicText(maskedText, paraphraseStrength); } if (homoglyphStrength > 0) { maskedText = applyUnicodeHomoglyphs(maskedText, homoglyphStrength); } if (zwspDensity > 0) { maskedText = injectZeroWidthSpaces(maskedText, zwspDensity); } return maskedText; } global.FritreeStealthLinguisticEngine = Object.freeze({ injectZWSP: injectZeroWidthSpaces, applyHomoglyphs: applyUnicodeHomoglyphs, paraphrase: autoParaphraseArabicText, processTextMasking: processTextStealthMasking, cleanImageExif: stripExifAndObfuscateMedia, thesaurus: ARABIC_SYNONYMS_THESAURUS }); })(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);