File size: 21,628 Bytes
cca0cf3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | /**
* @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<Blob>}
*/
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<Blob>}
*/
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<string>}
*/
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); |