<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: admin@adawati.app</title>
    <description>The latest articles on DEV Community by admin@adawati.app (@adawati).</description>
    <link>https://dev.to/adawati</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3841751%2F9937e80b-5adf-4d14-a2d1-d5f6ea145320.png</url>
      <title>DEV Community: admin@adawati.app</title>
      <link>https://dev.to/adawati</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adawati"/>
    <language>en</language>
    <item>
      <title>لماذا تحتاج تطبيقات الجداول إلى بريدي الإلكتروني؟ قمت ببرمجة بديل 100% Client-Side 📅🚀</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Mon, 27 Apr 2026 09:32:42 +0000</pubDate>
      <link>https://dev.to/adawati/lmdh-thtj-ttbyqt-ljdwl-l-brydy-llktrwny-qmt-bbrmj-bdyl-100-client-side-1fan</link>
      <guid>https://dev.to/adawati/lmdh-thtj-ttbyqt-ljdwl-l-brydy-llktrwny-qmt-bbrmj-bdyl-100-client-side-1fan</guid>
      <description>&lt;p&gt;لنكن صريحين. هل حاولت يوماً البحث عن تطبيق ويب بسيط لإنشاء جدول محاضرات أسبوعي؟&lt;/p&gt;

&lt;p&gt;عادةً ستواجه أحد هذين السيناريوهين:&lt;/p&gt;

&lt;p&gt;قالب إكسل (Excel) قديم ومزعج جداً عند التصفح من الجوال.&lt;/p&gt;

&lt;p&gt;تطبيق "حديث" يطلب بريدك الإلكتروني، ويجبرك على تفعيل الحساب، ثم يفاجئك بـ Paywall (اشتراك مدفوع) فقط لكي تقوم بتصدير جدولك كصورة.&lt;/p&gt;

&lt;p&gt;كل هذا العناء من أجل ترتيب 5 أو 6 مواد جامعية خلال الأسبوع!&lt;/p&gt;

&lt;p&gt;كمطور، وجدت هذا الأمر غير منطقي. تطبيق الجداول الأسبوعية لا يحتاج إلى Backend ثقيل، أو نظام مصادقة (Auth)، أو قاعدة بيانات. لذلك، قررت بناء &lt;a href="https://adawati.app/ar/timetable-builder/" rel="noopener noreferrer"&gt;صانع الجداول الجامعية لمنصة أدواتي&lt;/a&gt; — أداة سريعة جداً، تعمل 100% في متصفح العميل (Client-Side) بدون أي سيرفرات خلفية.&lt;/p&gt;

&lt;p&gt;إليكم كيف قمت ببنائها والتحديات التقنية التي تجاوزتها باستخدام الـ Web APIs القياسية. 🛠️&lt;/p&gt;

&lt;p&gt;🚫 نهج "اللا قاعدة بيانات" (إدارة الحالة محلياً)&lt;br&gt;
عندما تبني تطبيقاً بدون قاعدة بيانات، السؤال الأول الذي يتبادر للذهن هو: كيف نحفظ بيانات المستخدم حتى لا يفقدها إذا قام بتحديث الصفحة (Refresh)؟&lt;/p&gt;

&lt;p&gt;اعتمدت بشكل كبير على واجهة localStorage API.&lt;br&gt;
كلما قام المستخدم بإضافة مادة، يقوم التطبيق بتحديث مصفوفة (Array) تمثل الجدول، ويحولها إلى نص باستخدام JSON.stringify، ثم يحفظها محلياً. وعند تحميل الـ DOM، يتحقق التطبيق من الـ localStorage، ويقرأ الـ JSON، ويحدث واجهة المستخدم (UI) في أجزاء من الثانية.&lt;/p&gt;

&lt;p&gt;النتيجة؟ يحصل المستخدم على تجربة "الحفظ التلقائي" (Auto-save) المطابقة تماماً للتطبيقات السحابية، ولكن جدوله الأكاديمي لا يغادر جهازه الفعلي أبداً. خصوصية مطلقة، وتكلفة سيرفرات 0$ بالنسبة لي كمطور.&lt;/p&gt;

&lt;p&gt;⏱️ اكتشاف التعارض الزمني في المتصفح&lt;br&gt;
إذا أضفت محاضرة يوم الإثنين من الساعة 09:00 إلى 10:30، لا ينبغي أن يسمح لك النظام بإضافة محاضرة أخرى يوم الإثنين تبدأ الساعة 10:00.&lt;/p&gt;

&lt;p&gt;بدلاً من إرسال طلب HTTP إلى السيرفر للتحقق من هذا التعارض الزمني، كتبت خوارزمية تحقق خفيفة تعمل مباشرة في المتصفح.&lt;br&gt;
لتسهيل العمليات الحسابية، يحول التطبيق جميع الأوقات إلى "دقائق من منتصف الليل". وقبل حقن المادة الجديدة في الـ DOM، تمر الخوارزمية على المواد الموجودة في نفس اليوم وتتحقق من شرط التداخل الزمني:&lt;/p&gt;

&lt;p&gt;وقت البداية الجديد &amp;lt; وقت النهاية الموجود &amp;amp;&amp;amp; وقت النهاية الجديد &amp;gt; وقت البداية الموجود&lt;/p&gt;

&lt;p&gt;إذا تحقق الشرط، تظهر واجهة المستخدم تحذيراً فورياً. وبسبب عدم وجود تأخير في الشبكة (Zero Network Latency)، فإن الاستجابة تكون أسرع من البرق.&lt;/p&gt;

&lt;p&gt;🖼️ التحدي الأخير: تحويل الـ DOM إلى صورة PNG عالية الدقة&lt;br&gt;
الميزة الأولى التي يطلبها الطلاب هي القدرة على تحميل جدولهم كصورة لاستخدامها كخلفية لشاشة القفل في هواتفهم الذكية.&lt;/p&gt;

&lt;p&gt;تحويل تصميم HTML/CSS معقد (Grids, Flexbox, ونصوص مخصصة) إلى صورة قابلة للتحميل أمر صعب برمجياً. استخدمت Canvas API لأخذ "لقطة" (Snapshot) للـ DOM.&lt;br&gt;
لكن إذا قمت بذلك من قبل، فستعرف أن الصورة الناتجة غالباً ما تكون ضبابية (Blurry)، خاصة على شاشات الهواتف الحديثة (Retina Displays).&lt;/p&gt;

&lt;p&gt;الحل التقني: قمت برمجياً بإجبار الـ Canvas على التصيير (Render) بدقة 3x (ثلاثة أضعاف الدقة العادية) قبل إنشاء رابط البيانات (Base64 data URL). النتيجة هي صورة PNG فائقة الدقة يتم تحميلها مباشرة لجهاز المستخدم بدون أي طلب للسيرفر.&lt;/p&gt;

&lt;p&gt;👉 جربها بنفسك!&lt;br&gt;
إذا كنت تريد أن ترى مدى سلاسة تطبيقات الـ Client-side 100%، جرب بناء جدول سريع (وحاول أن تتعمد إحداث تعارض زمني لتختبر سرعة الخوارزمية) من هنا:&lt;br&gt;
&lt;a href="https://adawati.app/ar/timetable-builder/" rel="noopener noreferrer"&gt;صانع الجداول الجامعية&lt;/a&gt; - &lt;a href="https://adawati.app" rel="noopener noreferrer"&gt;أدواتي&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;سؤال لمجتمع المطورين: هل سبق لكم العمل بمكتبات تحويل الـ DOM إلى صور (مثل html2canvas)؟ وكيف تعاملتم مع مشكلة النصوص الضبابية أو اختلافات الـ CSS بين المتصفحات؟ شاركوني تجاربكم في التعليقات! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why do scheduling apps need my email? I built a 100% Client-Side Timetable Builder instead 📅🚀</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Mon, 27 Apr 2026 09:24:06 +0000</pubDate>
      <link>https://dev.to/adawati/why-do-scheduling-apps-need-my-email-i-built-a-100-client-side-timetable-builder-instead-3fbj</link>
      <guid>https://dev.to/adawati/why-do-scheduling-apps-need-my-email-i-built-a-100-client-side-timetable-builder-instead-3fbj</guid>
      <description>&lt;p&gt;Let’s be honest. Have you ever tried to find a simple web app to build a weekly schedule or timetable?&lt;/p&gt;

&lt;p&gt;You usually encounter two scenarios:&lt;/p&gt;

&lt;p&gt;It’s a clunky Excel template that looks terrible on mobile.&lt;/p&gt;

&lt;p&gt;It’s a "modern" app that demands your email, makes you verify your account, and then throws a paywall at you just to export your schedule.&lt;/p&gt;

&lt;p&gt;All of this just to map out 5 or 6 university courses across a week!&lt;/p&gt;

&lt;p&gt;As a developer, I found this ridiculous. A timetable app doesn't need a heavy backend, user authentication, or a database. So, I decided to build the &lt;a href="https://adawati.app/en/timetable-builder/" rel="noopener noreferrer"&gt;Adawati Timetable Builder&lt;/a&gt; — a blazing fast, 100% client-side scheduling tool with zero backend.&lt;/p&gt;

&lt;p&gt;Here is how I built it and the technical hurdles I bypassed using standard web APIs. 🛠️&lt;/p&gt;

&lt;p&gt;🚫 The "No-Database" Approach (State Persistence)&lt;br&gt;
When you build an app without a database, the immediate question is: How do we save the user's data so they don't lose it on refresh?&lt;/p&gt;

&lt;p&gt;I heavily relied on the localStorage API.&lt;br&gt;
Whenever a user adds a course, the app updates an array of objects representing the schedule, stringifies it, and saves it locally. When the DOM loads, it checks localStorage, parses the JSON, and hydrates the UI instantly.&lt;/p&gt;

&lt;p&gt;The result? The user gets an "auto-save" experience identical to a cloud app, but their academic schedule never leaves their physical device. Absolute privacy, and $0 server costs for me.&lt;/p&gt;

&lt;p&gt;⏱️ Detecting Time Conflicts in the Browser&lt;br&gt;
If you add a class on Monday from 09:00 to 10:30, you shouldn't be able to add another Monday class at 10:00.&lt;/p&gt;

&lt;p&gt;Instead of sending an HTTP request to a server to validate this payload, I wrote a lightweight validation engine that runs in the browser.&lt;br&gt;
To make the math easy, the app converts all times into "minutes from midnight". Before a new course is injected into the DOM, the algorithm loops through the existing courses for that day and checks for overlaps:&lt;/p&gt;

&lt;p&gt;New Start Time &amp;lt; Existing End Time &amp;amp;&amp;amp; New End Time &amp;gt; Existing Start Time&lt;/p&gt;

&lt;p&gt;If it returns true, the UI instantly throws a warning. Because there is no network latency, the feedback is lightning-fast.&lt;/p&gt;

&lt;p&gt;🖼️ The Final Boss: DOM to High-Res PNG&lt;br&gt;
The number one feature students want is the ability to download their timetable to use as a phone lock screen.&lt;/p&gt;

&lt;p&gt;Converting a complex HTML/CSS layout (grids, flexbox, text) into a downloadable image is notoriously tricky. I used the Canvas API to take a "snapshot" of the DOM.&lt;br&gt;
However, if you've ever done this, you know the exported image often looks blurry, especially on Retina displays.&lt;/p&gt;

&lt;p&gt;The fix: I programmatically forced the Canvas to render at 3x the normal resolution before generating the Base64 data URL. The result is a beautifully crisp PNG that downloads directly to the user's device without a single server round-trip.&lt;/p&gt;

&lt;p&gt;👉 Try it out yourself!&lt;br&gt;
If you want to see how smooth a 100% client-side app can feel, try building a quick schedule (and try to trigger the time conflict warning) here:&lt;br&gt;
&lt;a href="https://adawati.app/en/timetable-builder/" rel="noopener noreferrer"&gt;Adawati Timetable Builder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Question for the dev community: Have you ever worked with DOM-to-Image libraries (like html2canvas)? How did you handle the blurry text issue or CSS cross-browser quirks? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>الخلل البرمجي والرياضي في طرق تحويل المعدل الجامعي للطلاب المبتعثين</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Thu, 23 Apr 2026 20:15:41 +0000</pubDate>
      <link>https://dev.to/adawati/lkhll-lbrmjy-wlrydy-fy-trq-thwyl-lmdl-ljmy-lltlb-lmbtthyn-4o5m</link>
      <guid>https://dev.to/adawati/lkhll-lbrmjy-wlrydy-fy-trq-thwyl-lmdl-ljmy-lltlb-lmbtthyn-4o5m</guid>
      <description>&lt;p&gt;كطلاب في تخصصات علوم الحاسب والهندسة، أو كمطورين نسعى للتقديم على برامج الماجستير في الخارج أو التدريب في الشركات التقنية العالمية، غالباً ما نصطدم بمتطلب أساسي في استمارات القبول: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"أدخل معدلك التراكمي على مقياس 4.0"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;بما أن معظم جامعاتنا العربية (في السعودية والخليج) تعتمد نظام 5.0 أو النسبة المئوية، فإن أول حل يتبادر لذهن المبرمج هو استخدام دالة رياضية خطية بسيطة للتحويل: &lt;code&gt;(4.5 / 5.0) * 4.0 = 3.6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;هذا الخطأ الرياضي قد يكلفك فرصة القبول!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  المشكلة: المقاييس الأكاديمية ليست خطية (Non-Linear)
&lt;/h3&gt;

&lt;p&gt;أنظمة التقييم الأكاديمي لا تعمل بنظام النسبة والتناسب المباشر. في نظام 5.0، تقدير (B+) يمنحك 4.5 نقطة. لكن في نظام 4.0، نفس التقدير (B+) يعادل 3.5 نقطة وليس 3.6. استخدام القسمة المباشرة يخفض من قيمة معدلك الحقيقي ويجعلك تتراجع في أنظمة الفرز الآلي (ATS) الخاصة بالجامعات والشركات.&lt;/p&gt;

&lt;h3&gt;
  
  
  الحل التقني: محول درجات يعتمد على مصفوفة معتمدة
&lt;/h3&gt;

&lt;p&gt;لحل هذه الفجوة، قمنا بهندسة أداة &lt;strong&gt;&lt;a href="https://adawati.app/ar/grade-converter/" rel="noopener noreferrer"&gt;محول الدرجات من منصة أدواتي&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;الأداة لا تعتمد على القسمة، بل تتضمن مصفوفة برمجية (Matrix) مبنية على لوائح تحويل الدرجات الرسمية (مثل جداول WES ووزارة التعليم). بمجرد إدخال معدلك، تقوم الأداة بإرجاع قيمتك بدقة عبر 4 أنظمة في نفس اللحظة:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;مقياس 5.0&lt;/li&gt;
&lt;li&gt;مقياس 4.0&lt;/li&gt;
&lt;li&gt;النسبة المئوية (%)&lt;/li&gt;
&lt;li&gt;التقدير الحرفي&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  لماذا صممناها لتعمل من جهة العميل (Client-Side)؟
&lt;/h3&gt;

&lt;p&gt;كمهندسين ومطورين، الخصوصية لدينا خط أحمر. السجلات الأكاديمية تعتبر بيانات حساسة جداً. لذلك، اتخذنا قراراً هندسياً بأن نجعل الأداة تعمل بالكامل داخل المتصفح.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;بدون خوادم (Zero Server Logs):&lt;/strong&gt; حساب الدرجات يتم عبر JavaScript في جهازك المحلي.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;سرعة لحظية:&lt;/strong&gt; عدم وجود طلبات (API Calls) للخادم يعني أن النتائج تظهر بمجرد كتابة الرقم.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;أمان 100%:&lt;/strong&gt; لا يتم إرسال أو تخزين أي درجة في قواعد بياناتنا.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  جرب الأداة الآن
&lt;/h3&gt;

&lt;p&gt;إذا كنت تجهز سيرتك الذاتية أو أوراق الابتعاث، لا تعتمد على التخمين. &lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://adawati.app/ar/grade-converter/" rel="noopener noreferrer"&gt;استخدم محول الدرجات الأكاديمي مجاناً من هنا&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(ملاحظة للمطورين: منصة "أدواتي" تحتوي أيضاً على أدوات لمعالجة الـ PDF تفاعلياً داخل المتصفح، وأدوات ذكاء اصطناعي لتفريغ المحاضرات. يسعدني جداً سماع رأيكم في الواجهة البرمجية وتجربة المستخدم في التعليقات!)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>arabic</category>
      <category>students</category>
      <category>engineering</category>
      <category>saudiarabia</category>
    </item>
    <item>
      <title>Why Linear Math is Ruining Your GPA Conversion (And the Client-Side Tool I Built to Fix It)</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Thu, 23 Apr 2026 20:13:58 +0000</pubDate>
      <link>https://dev.to/adawati/why-linear-math-is-ruining-your-gpa-conversion-and-the-client-side-tool-i-built-to-fix-it-3cjk</link>
      <guid>https://dev.to/adawati/why-linear-math-is-ruining-your-gpa-conversion-and-the-client-side-tool-i-built-to-fix-it-3cjk</guid>
      <description>&lt;p&gt;If you’re an international CS student or software engineer applying for grad school, scholarships, or internships at global tech companies, you’ve hit this wall: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Please enter your GPA on a 4.0 scale."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your university uses a 5.0 scale or a Percentage (%) system, your first instinct as a programmer is probably to write a quick script or use linear math to cross-multiply. &lt;br&gt;
For example: &lt;code&gt;(4.5 / 5.0) * 4.0 = 3.6&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop right there. That math is fatally flawed.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem: Academic Scales are Non-Linear
&lt;/h3&gt;

&lt;p&gt;Unlike straightforward data conversions, academic grading scales are heavily weighted and non-linear. In a 5.0 system, a (B+) is typically 4.5 points. However, on the US 4.0 scale, a (B+) drops to 3.5 points, not 3.6. &lt;/p&gt;

&lt;p&gt;Using simple linear conversion actually &lt;em&gt;undervalues&lt;/em&gt; your academic performance, potentially costing you a spot in a competitive Master's program or bypassing the ATS (Applicant Tracking System) filters for junior developer roles.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: A Privacy-First Grade Converter
&lt;/h3&gt;

&lt;p&gt;I got tired of seeing brilliant students get rejected due to bad math, so my team and I built the &lt;strong&gt;&lt;a href="https://adawati.app/en/grade-converter/" rel="noopener noreferrer"&gt;Adawati Grade Converter&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of linear math, the tool uses the official conversion brackets (like those from WES and Ministries of Education) to map your exact letter grade equivalent across four different systems simultaneously:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GPA 5.0 Scale&lt;/li&gt;
&lt;li&gt;GPA 4.0 Scale&lt;/li&gt;
&lt;li&gt;Percentage (%)&lt;/li&gt;
&lt;li&gt;Letter Grade (A, B, C...)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Developer Angle: Why We Built It Client-Side
&lt;/h3&gt;

&lt;p&gt;As developers, we are naturally paranoid about our data. Academic transcripts are highly sensitive. &lt;/p&gt;

&lt;p&gt;We engineered the Adawati Grade Converter to be &lt;strong&gt;100% Client-Side&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero Server Logs:&lt;/strong&gt; Your grades are processed entirely within your browser's DOM using JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Databases:&lt;/strong&gt; We don't send a single byte of your academic data to our servers. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant Speed:&lt;/strong&gt; Because there are no API calls to a backend, the conversion matrix updates in real-time as you type.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test It Out
&lt;/h3&gt;

&lt;p&gt;If you are preparing your resume or grad school applications, don't guess your GPA. Do it the right way.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://adawati.app/en/grade-converter/" rel="noopener noreferrer"&gt;Try the Adawati Grade Converter Here (Free &amp;amp; No Ads)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(P.S. We also built a suite of client-side PDF tools and an AI Audio-to-Text transcriber on the same platform. Let me know what you think of the UI/UX in the comments!)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>students</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building a Bulletproof GPA Calculator: Battling JavaScript Floating Point Math 🧮💥</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Thu, 23 Apr 2026 16:26:46 +0000</pubDate>
      <link>https://dev.to/adawati/building-a-bulletproof-gpa-calculator-battling-javascript-floating-point-math-33eh</link>
      <guid>https://dev.to/adawati/building-a-bulletproof-gpa-calculator-battling-javascript-floating-point-math-33eh</guid>
      <description>&lt;p&gt;Let’s talk about building calculators in JavaScript. On the surface, it sounds like a beginner's project: Just multiply Grade Points by Credit Hours, sum them up, and divide by the total. Easy, right?&lt;/p&gt;

&lt;p&gt;Well, that's what I thought until I decided to build a comprehensive, dual-scale (4.0 &amp;amp; 5.0) University GPA Calculator for &lt;a href="https://adawati.app/en/gpa-calculator/" rel="noopener noreferrer"&gt;Adawati.app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It quickly turned into a lesson in why JavaScript math can be a developer's worst enemy when absolute precision is required. Here is how I built a robust, 100% client-side GPA engine without a backend.&lt;/p&gt;

&lt;p&gt;🛑 The Core Problem: The 0.1 + 0.2 Nightmare&lt;br&gt;
As we all know, JavaScript uses double-precision 64-bit format IEEE 754 values. This means doing something as simple as summing up quality points can sometimes result in 3.1000000000000005.&lt;/p&gt;

&lt;p&gt;When you are dealing with a student's GPA—where the difference between a 3.99 and a 4.00 dictates whether they graduate with Honors—rounding errors are unacceptable.&lt;/p&gt;

&lt;p&gt;To solve this, I couldn't rely on raw float addition. Instead, I structured the calculation pipeline to multiply values by an order of magnitude (e.g., 100), perform the integer math, and then divide back down just before rendering the final result.&lt;/p&gt;

&lt;p&gt;⚙️ Managing Dual Grading Scales (The Smart Way)&lt;br&gt;
Most universities in the US use a 4.0 scale, but in the Middle East, the 5.0 scale is heavily prevalent. I didn’t want to write two separate calculation engines.&lt;/p&gt;

&lt;p&gt;Instead, I created a unified state dictionary. The core logic remains identical, but the grade-to-point mapping acts as a configuration object that swaps out dynamically when the user toggles the scale button.&lt;/p&gt;

&lt;p&gt;JavaScript&lt;br&gt;
// A simplified example of the state mapping&lt;br&gt;
const scaleMappings = {&lt;br&gt;
  "5.0": { "A+": 5.0, "A": 4.75, "B+": 4.5 /* ... &lt;em&gt;/ },&lt;br&gt;
  "4.0": { "A+": 4.0, "A": 4.0, "B+": 3.5 /&lt;/em&gt; ... */ }&lt;br&gt;
};&lt;br&gt;
This keeps the logic completely decoupled from the UI and makes adding future scales (like the UK grading system) incredibly easy.&lt;/p&gt;

&lt;p&gt;🔮 The Cumulative "What-If" Engine&lt;br&gt;
The real value of a GPA tool is the "What-If" simulator—allowing students to see how next semester's grades will impact their overall standing.&lt;/p&gt;

&lt;p&gt;This required combining historical data (Previous GPA × Previous Hours) with the active DOM inputs (Current Courses). Because I wanted this to be a zero-latency tool, the entire reactivity happens directly in the browser. The moment a user selects an A- from a dropdown, the DOM fires an event that updates the total quality points and recalculates the cumulative GPA instantly, without a single server request.&lt;/p&gt;

&lt;p&gt;🔒 Why Client-Side First?&lt;br&gt;
A key philosophy behind &lt;a href="https://adawati.app/en/" rel="noopener noreferrer"&gt;Adawati&lt;/a&gt; is privacy. Academic standing is personal data. By executing the complex math entirely within the user's browser, I ensure that their grades are never logged, stored, or transmitted to a server.&lt;/p&gt;

&lt;p&gt;👉 Try the Engine&lt;br&gt;
You can test out the live GPA calculator (and try to break the floating-point math) here:&lt;br&gt;
&lt;a href="https://adawati.app/en/gpa-calculator/" rel="noopener noreferrer"&gt;Adawati GPA Calculator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the Devs: How do you usually handle precise decimal math in JS? Do you use libraries like Big.js or Decimal.js, or do you prefer writing your own helper functions for small-scale applications like this? Let me know! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>algorithms</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Stop uploading PDFs to random servers! I built a 100% Client-Side PDF Editor in JS 🛡️📄</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Tue, 21 Apr 2026 09:42:39 +0000</pubDate>
      <link>https://dev.to/adawati/stop-uploading-pdfs-to-random-servers-i-built-a-100-client-side-pdf-editor-in-js-23fd</link>
      <guid>https://dev.to/adawati/stop-uploading-pdfs-to-random-servers-i-built-a-100-client-side-pdf-editor-in-js-23fd</guid>
      <description>&lt;p&gt;Let’s be real for a second. Every time you or a family member needs to merge, split, or compress a PDF, what do you do? You Google "Free PDF Editor," click the first result, and upload your highly sensitive document (like a bank statement, resume, or legal contract) to a random server halfway across the world.&lt;/p&gt;

&lt;p&gt;Then you just hope they actually delete it like their privacy policy claims.&lt;/p&gt;

&lt;p&gt;As a web developer, I found this absurd. Today's browsers are incredibly powerful, so why are we still relying on backend servers to do basic file manipulation?&lt;/p&gt;

&lt;p&gt;To solve this, I built the &lt;a href="https://adawati.app/en/pdf-editor/" rel="noopener noreferrer"&gt;Adawati PDF Editor&lt;/a&gt; — a completely free, zero-latency, and 100% client-side PDF toolkit.&lt;/p&gt;

&lt;p&gt;Here is how I bypassed the backend and built this entirely in the browser using JavaScript. 🛠️&lt;/p&gt;

&lt;p&gt;🧠 The Magic of ArrayBuffer and Blob&lt;br&gt;
The traditional way of handling files on the web is grabbing a file input, attaching it to a FormData object, and POSTing it to an API.&lt;/p&gt;

&lt;p&gt;But with a client-side approach, we don't do that. Instead, when a user selects a PDF, the app uses the FileReader API to read the file directly into the browser's memory as an ArrayBuffer.&lt;/p&gt;

&lt;p&gt;By treating the PDF as raw binary data (Uint8Array), the JavaScript engine can parse the document's structure. Whether the user wants to merge two documents, extract specific pages, or compress the file, the app mutates the binary data directly in the browser's memory.&lt;/p&gt;

&lt;p&gt;🚀 Zero Latency &amp;amp; No Progress Bars&lt;br&gt;
Because nothing is being uploaded or downloaded from a remote server, the speed is mind-blowing.&lt;br&gt;
Editing a PDF is constrained only by the user's CPU, not their internet connection. There are no "uploading..." spinners or timeout errors for large files.&lt;/p&gt;

&lt;p&gt;📥 Downloading Without a Server&lt;br&gt;
How do you serve the modified file back to the user if there is no backend to generate a download link?&lt;br&gt;
You create a Blob!&lt;/p&gt;

&lt;p&gt;Once the binary manipulation is complete, the app packages the new Uint8Array into a PDF Blob. Using URL.createObjectURL(), it generates a temporary local URL, attaches it to a hidden &lt;a&gt; tag, and triggers a programmatic click.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file saves instantly to the user's local machine.&lt;/p&gt;

&lt;p&gt;🔒 Privacy by Design&lt;br&gt;
The biggest win here isn't just speed—it’s absolute security. Because the architecture lacks a backend to process the files, it is physically impossible for the documents to be intercepted, stored, or leaked by the platform. You can literally load the page, turn off your Wi-Fi, and edit your PDFs offline.&lt;/p&gt;

&lt;p&gt;Try it out!&lt;br&gt;
I built this as part of a larger suite of privacy-first tools for students and professionals. You can test the PDF editor (Merge, Split, Compress, etc.) live here:&lt;br&gt;
👉 &lt;a href="https://adawati.app/en/pdf-editor/" rel="noopener noreferrer"&gt;Adawati PDF Editor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Question for the dev community: Have you ever had to work with PDFs in your projects? What libraries or approaches did you use? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I got tired of bloated writing apps, so I built a Zero-Latency, Privacy-First Document Editor ⚡</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Tue, 14 Apr 2026 10:56:14 +0000</pubDate>
      <link>https://dev.to/adawati/i-got-tired-of-bloated-writing-apps-so-i-built-a-zero-latency-privacy-first-document-editor-93j</link>
      <guid>https://dev.to/adawati/i-got-tired-of-bloated-writing-apps-so-i-built-a-zero-latency-privacy-first-document-editor-93j</guid>
      <description>&lt;p&gt;Modern writing tools are amazing, but let’s be honest: they have become incredibly bloated. Opening a simple document today often means loading megabytes of JavaScript, waiting for server syncs, and accepting that every single keystroke is being tracked and stored in a database somewhere.&lt;/p&gt;

&lt;p&gt;Sometimes, you just need a fast, clean, and private space to write your thoughts, draft a blog post, or structure a document without the overhead.&lt;/p&gt;

&lt;p&gt;That’s exactly why I built &lt;a href="https://adawati.app/en/docs/" rel="noopener noreferrer"&gt;Adawati Docs&lt;/a&gt; — a lightweight, distraction-free document editor that runs directly in your browser.&lt;/p&gt;

&lt;p&gt;You can try it live here: &lt;a href="https://adawati.app/en/docs/" rel="noopener noreferrer"&gt;Adawati Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🛠️ The Core Philosophy: Speed and Privacy&lt;br&gt;
When designing this editor, I had two strict rules:&lt;/p&gt;

&lt;p&gt;Zero Latency: The editor must load instantly. No waiting for spinners or database connections.&lt;/p&gt;

&lt;p&gt;Absolute Privacy: What you write is your business. The text should not be sent to any backend server for rendering or storage.&lt;/p&gt;

&lt;p&gt;💻 Technical Highlights&lt;br&gt;
To achieve this, I leaned heavily on a Client-Side First architecture. Here is how it works under the hood:&lt;/p&gt;

&lt;p&gt;Browser as the Backend: Instead of relying on a database to save drafts, the editor leverages local storage mechanisms. Your document lives in your browser's memory. If you close the tab and come back, your work is exactly where you left it—all without a single API call.&lt;/p&gt;

&lt;p&gt;Rich Formatting, Zero Bloat: Implementing a rich text editor that supports essential formatting (headings, lists, bolding) without turning the app into a sluggish monster was a challenge. By keeping the DOM manipulations clean and avoiding heavy third-party WYSIWYG dependencies, the typing experience remains buttery smooth.&lt;/p&gt;

&lt;p&gt;Exporting Made Simple: Once you are done writing, you need to get your text out efficiently. The tool allows you to format your document and copy it cleanly, preserving the structure so you can paste it directly into your CMS, emails, or markdown files without weird inline CSS issues.&lt;/p&gt;

&lt;p&gt;🌍 Fully Localized&lt;br&gt;
Just like the rest of the &lt;a href="https://adawati.app/en/" rel="noopener noreferrer"&gt;Adawati&lt;/a&gt; platform, I made sure the editor handles both English (LTR) and Arabic (RTL) perfectly. Handling bi-directional text gracefully in an editor requires strict attention to CSS logical properties to ensure the cursor and text alignment don't break when switching languages.&lt;/p&gt;

&lt;p&gt;🚀 What's Next?&lt;br&gt;
Building &lt;a href="https://adawati.app/en/docs/" rel="noopener noreferrer"&gt;Adawati Docs&lt;/a&gt; has been a great exercise in performance optimization and trusting the client's browser capabilities. My next goal is to add direct Markdown-to-PDF exporting entirely on the client-side.&lt;/p&gt;

&lt;p&gt;I would love for you to test the editor and try writing your next post or notes on it: &lt;a href="https://adawati.app/en/docs/" rel="noopener noreferrer"&gt;Adawati Docs/Editor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What is your current go-to tool for quick, distraction-free writing? Let me know in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>javascript</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>How I Built a 100% Client-Side, ATS-Friendly CV Builder (Zero Backend for Ultimate Privacy</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Sat, 04 Apr 2026 18:57:05 +0000</pubDate>
      <link>https://dev.to/adawati/how-i-built-a-100-client-side-ats-friendly-cv-builder-zero-backend-for-ultimate-privacy-4g8g</link>
      <guid>https://dev.to/adawati/how-i-built-a-100-client-side-ats-friendly-cv-builder-zero-backend-for-ultimate-privacy-4g8g</guid>
      <description>&lt;p&gt;Have you ever spent an hour filling out your details on a "free" resume builder, only to be hit with a $15 paywall or a massive, ugly watermark right when you click download?&lt;/p&gt;

&lt;p&gt;As an indie developer, I found this practice incredibly frustrating. Beyond the hidden fees, there's a massive privacy concern: why should a random server store my phone number, address, and entire employment history just to generate a PDF?&lt;/p&gt;

&lt;p&gt;So, I decided to build my own free alternative on &lt;a href="https://adawati.app/" rel="noopener noreferrer"&gt;Adawati.app&lt;/a&gt;: a fast, ATS-friendly CV builder that operates 100% on the client-side. No backend storage, no hidden fees.&lt;/p&gt;

&lt;p&gt;Here is how I approached the technical challenges.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Core Architecture: Zero Backend
The primary goal was privacy. By eliminating the backend from the PDF generation process, the user's sensitive data never leaves their browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of sending JSON payloads to a Node.js or Python server to render a PDF using tools like Puppeteer or ReportLab, the entire heavy lifting is done in the DOM.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The ATS (Applicant Tracking System) Challenge
A major trap with client-side PDF generation is taking the easy route: converting a DOM element to an HTML canvas (e.g., using html2canvas) and then putting that image into a PDF.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why is this bad? Because ATS bots cannot read images! If your resume is just a giant image inside a PDF wrapper, you will automatically be rejected by 75% of corporate filtering systems.&lt;/p&gt;

&lt;p&gt;The Solution:&lt;br&gt;
I had to ensure the output was a true vector PDF with selectable text. Using client-side libraries that construct the PDF document programmatically ensures that the text layer is preserved. The file remains lightweight, the text is razor-sharp (no pixelation on zoom), and most importantly, an ATS can easily parse the keywords, job titles, and dates.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Handling RTL (Right-to-Left) and Localization&lt;br&gt;
Since the platform targets both Arabic and English speakers, the layout had to mirror perfectly without breaking the PDF generation flow.&lt;br&gt;
Switching between languages triggers a state change that not only flips the CSS (direction: rtl) for the live preview but also maps to the corresponding coordinates and text alignments in the PDF generation logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Result&lt;br&gt;
The final product allows users to:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Type their data and see a Live Preview.&lt;/p&gt;

&lt;p&gt;Switch between English and Arabic seamlessly.&lt;/p&gt;

&lt;p&gt;Download a clean, ATS-compliant PDF instantly.&lt;/p&gt;

&lt;p&gt;You can try the live tool here: &lt;a href="https://adawati.app/en/cv-builder/" rel="noopener noreferrer"&gt;Adawati CV Builder&lt;/a&gt;. Turn off your Wi-Fi before clicking download if you want to test the "Client-Side only" claim! 😉&lt;/p&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
Building tools that respect user privacy shouldn't be the exception; it should be the norm. My next challenge is optimizing the client-side PDF compression.&lt;/p&gt;

&lt;p&gt;Have you worked with client-side PDF generation before? What libraries did you find most reliable for handling complex layouts and custom fonts? Let me know in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>🚀 Building a High-Accuracy Arabic OCR Tool: How I Solved the "Image-to-Text" Challenge</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:02:43 +0000</pubDate>
      <link>https://dev.to/adawati/building-a-high-accuracy-arabic-ocr-tool-how-i-solved-the-image-to-text-challenge-52dc</link>
      <guid>https://dev.to/adawati/building-a-high-accuracy-arabic-ocr-tool-how-i-solved-the-image-to-text-challenge-52dc</guid>
      <description>&lt;p&gt;Extraction of text from images (OCR) is a solved problem for Latin languages, but for Arabic, it’s a whole different story. As the developer behind &lt;a href="https://adawati.app/" rel="noopener noreferrer"&gt;Adawati.app&lt;/a&gt;, I spent weeks engineering a solution that doesn't just "read" Arabic, but understands its complexity.&lt;/p&gt;

&lt;p&gt;The Problem: Why Arabic OCR is Hard&lt;br&gt;
Most open-source OCR engines struggle with Arabic for three reasons:&lt;/p&gt;

&lt;p&gt;Cursive Nature: Arabic letters change shape based on their position (Start, Middle, End).&lt;/p&gt;

&lt;p&gt;Diacritics &amp;amp; Dots: Small dots and marks can change the entire meaning of a word.&lt;/p&gt;

&lt;p&gt;Low-Quality Input: Students often take photos of textbooks in poor lighting or at weird angles.&lt;/p&gt;

&lt;p&gt;My Engineering Approach&lt;br&gt;
Instead of just "plugging in" a generic API, I built a pipeline focused on Pre-processing and Contextual Inference.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Image Pre-processing (The Secret Sauce)
Before the AI even looks at the image, I apply several filters:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Binarization: Converting the image to high-contrast black and white to eliminate background noise.&lt;/p&gt;

&lt;p&gt;Deskewing: Automatically correcting the angle if the photo was taken tilted.&lt;/p&gt;

&lt;p&gt;Noise Reduction: Removing "salt and pepper" noise often found in scanned PDFs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The AI Engine&lt;br&gt;
I utilized state-of-the-art deep learning models specifically fine-tuned for Arabic scripts. These models use CNNs (Convolutional Neural Networks) for visual feature extraction and LSTMs (Long Short-Term Memory) to understand the sequence of characters, ensuring that the connected letters are recognized as a coherent word, not just random symbols.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Privacy-First Architecture&lt;br&gt;
In an era of data harvesting, I made a conscious architectural decision: Zero Retention.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Images are processed in a secure memory buffer.&lt;/p&gt;

&lt;p&gt;Once the text is extracted, the image is purged instantly.&lt;/p&gt;

&lt;p&gt;No databases, no logs of your documents.&lt;/p&gt;

&lt;p&gt;Why I Built This?&lt;br&gt;
I saw students struggling to transcribe their lectures and researchers stuck with non-searchable PDF archives. I wanted to provide a free, fast, and no-login tool that respects their privacy while delivering professional-grade accuracy.&lt;/p&gt;

&lt;p&gt;Try it out&lt;br&gt;
If you're a developer interested in Arabic NLP or a student looking for a reliable tool, check it out here:&lt;br&gt;
&lt;a href="https://adawati.app/image-to-text/" rel="noopener noreferrer"&gt;👉 Image to Text - Arabic OCR Tool&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback on the accuracy, especially with complex fonts or handwritten notes!&lt;/p&gt;

&lt;h1&gt;
  
  
  Arabic #OCR #AI #WebDev #Productivity #NextJS
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>title: Building a Free Arabic Speech-to-Text Engine using Hugging Face &amp; Next.js</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Wed, 25 Mar 2026 13:06:10 +0000</pubDate>
      <link>https://dev.to/adawati/title-building-a-free-arabic-speech-to-text-engine-using-hugging-face-nextjs-29b9</link>
      <guid>https://dev.to/adawati/title-building-a-free-arabic-speech-to-text-engine-using-hugging-face-nextjs-29b9</guid>
      <description>&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;Hello fellow developers! 👋&lt;/p&gt;

&lt;p&gt;Handling audio processing in web applications is always tricky, but when you add &lt;strong&gt;Arabic dialects and academic terminology (Arabizi)&lt;/strong&gt; to the mix, it becomes a real engineering challenge.&lt;/p&gt;

&lt;p&gt;Recently, while building &lt;a href="https://adawati.app" rel="noopener noreferrer"&gt;Adawati.app&lt;/a&gt; (an all-in-one digital workspace for Arab students), I needed to implement a reliable Speech-to-Text (STT) feature for university lectures. Paid APIs like Google Cloud or AWS were either too expensive for a free tool or struggled heavily with local Arabic dialects. &lt;/p&gt;

&lt;p&gt;Here is how I engineered a custom, free solution using &lt;strong&gt;Hugging Face&lt;/strong&gt; open-source models.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛑 The Technical Bottlenecks
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Large File Uploads &amp;amp; Timeouts:&lt;/strong&gt; University lectures are often 1-2 hours long. Sending a 100MB audio file to a server in one go usually results in a &lt;code&gt;504 Gateway Timeout&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background Noise:&lt;/strong&gt; Lecture halls are noisy. Passing raw audio to an AI model drastically reduces transcription accuracy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dialect Nuances:&lt;/strong&gt; Standard Arabic models fail when professors mix English technical terms with local Arabic dialects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ⚙️ The Architecture &amp;amp; Solution
&lt;/h3&gt;

&lt;p&gt;To bypass these issues, I built a pipeline that processes the audio efficiently:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Audio Chunking (The Game Changer)&lt;/strong&gt;&lt;br&gt;
Instead of sending the whole file, I used the Web Audio API on the client-side to split the audio into smaller 30-second chunks before sending them to the backend. This prevents timeouts and allows parallel processing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Pre-processing &amp;amp; Noise Reduction&lt;/strong&gt;&lt;br&gt;
Before hitting the AI model, the chunks go through a basic noise-reduction filter using &lt;code&gt;FFmpeg&lt;/code&gt; to isolate human voice frequencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Hugging Face Inference&lt;/strong&gt;&lt;br&gt;
I connected the backend to a fine-tuned Whisper model hosted on Hugging Face, specifically trained on Arabic datasets. &lt;/p&gt;

&lt;p&gt;Here is a conceptual snippet of how the chunking logic looks in the backend (Python/FastAPI wrapper):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`python&lt;br&gt;
from pydub import AudioSegment&lt;br&gt;
import requests&lt;/p&gt;

&lt;p&gt;def process_large_audio(file_path):&lt;br&gt;
    audio = AudioSegment.from_file(file_path)&lt;br&gt;
    chunk_length_ms = 30000 # 30 seconds&lt;br&gt;
    chunks = [audio[i:i+chunk_length_ms] for i in range(0, len(audio), chunk_length_ms)]&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;full_transcript = ""

for idx, chunk in enumerate(chunks):
    chunk.export(f"temp_chunk_{idx}.wav", format="wav")
    # Send to Hugging Face API
    transcript = query_huggingface(f"temp_chunk_{idx}.wav")
    full_transcript += transcript + " "

return full_transcript`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;🚀 The Live Result&lt;br&gt;
By combining this chunking architecture with Hugging Face models, I managed to create a fast, accurate, and completely free lecture transcription tool without relying on expensive enterprise APIs.&lt;/p&gt;

&lt;p&gt;You can test the live implementation and its accuracy with Arabic audio here:&lt;br&gt;
👉 &lt;a href="https://adawati.app/en/audio-to-text/" rel="noopener noreferrer"&gt;Arabic Audio-to-Text Converter&lt;/a&gt; - Adawati&lt;/p&gt;

&lt;p&gt;💬 Let's Discuss!&lt;br&gt;
I'm curious to know from the backend engineers here:&lt;br&gt;
How do you handle massive file uploads in your Next.js/Node.js applications? Do you prefer client-side chunking or streaming directly to a cloud bucket (like AWS S3) before processing?&lt;/p&gt;

&lt;p&gt;Let me know in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nextjs</category>
      <category>nlp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>كيف قمت بحل مشكلة انعكاس الحروف العربية (RTL) عند استخراج</title>
      <dc:creator>admin@adawati.app</dc:creator>
      <pubDate>Tue, 24 Mar 2026 14:01:54 +0000</pubDate>
      <link>https://dev.to/adawati/kyf-qmt-bhl-mshkl-nks-lhrwf-lrby-rtl-nd-stkhrj-4pm7</link>
      <guid>https://dev.to/adawati/kyf-qmt-bhl-mshkl-nks-lhrwf-lrby-rtl-nd-stkhrj-4pm7</guid>
      <description>&lt;p&gt;`---&lt;br&gt;
title: "كيف قمت بحل مشكلة انعكاس الحروف العربية (RTL) عند استخراج النصوص من ملفات PDF"&lt;br&gt;
published: true&lt;/p&gt;

&lt;h2&gt;
  
  
  tags: webdev, pdf, arabic, programming
&lt;/h2&gt;

&lt;p&gt;مرحباً أصدقائي المطورين،&lt;/p&gt;

&lt;p&gt;أي شخص حاول التعامل مع ملفات الـ PDF برمجياً لاستخراج النصوص العربية يعرف تماماً هذا الكابوس: تسحب النص فتجده معكوساً (م ر ح ب ا)، أو تجد الحروف متقطعة وغير متصلة. &lt;/p&gt;

&lt;p&gt;خلال عملي مؤخراً على بناء أدوات لمعالجة المستندات للطلاب، واجهت هذه المشكلة بعمق. حاولت استخدام مكتبات شهيرة مثل &lt;code&gt;pdf.js&lt;/code&gt; أو &lt;code&gt;PyPDF2&lt;/code&gt;، لكن النتيجة مع اللغة العربية كانت دائماً كارثية.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔍 ما هو جذر المشكلة؟
&lt;/h3&gt;

&lt;p&gt;المشكلة تكمن في أن ملفات الـ PDF لا تفهم "الكلمات" أو "الفقرات". هي ببساطة تتعامل مع المستند كـ "لوحة رسم" (Canvas)، وتقوم بوضع كل حرف في إحداثيات (X, Y) محددة. اللغات اللاتينية تُكتب من اليسار لليمين (LTR)، ومحركات الاستخراج تقرأ الإحداثيات بهذا الترتيب. أما العربية (RTL)، فيتم رسمها من اليمين لليسار، وعندما يقرأها المحرك برمجياً من اليسار لليمين، تخرج الكلمة معكوسة!&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ كيف قمت بحلها؟
&lt;/h3&gt;

&lt;p&gt;بدلاً من الاعتماد على القراءة النصية التقليدية للإحداثيات، قمت بدمج مكتبات إعادة التشكيل (Reshaping) وخوارزميات ثنائية الاتجاه (Bidi Algorithm) كطبقة معالجة وسيطة، بالإضافة للاستعانة بنماذج ذكاء اصطناعي عبر Hugging Face متخصصة في الـ OCR لمعالجة الحالات المستعصية.&lt;/p&gt;

&lt;p&gt;الفكرة البرمجية المبسطة تعتمد على تمرير النص المستخرج عبر هذه الفلاتر:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`python&lt;br&gt;
import arabic_reshaper&lt;br&gt;
from bidi.algorithm import get_display&lt;/p&gt;

&lt;p&gt;def fix_arabic_pdf_text(raw_text):&lt;br&gt;
    # 1. إعادة ربط الحروف العربية المتقطعة&lt;br&gt;
    reshaped_text = arabic_reshaper.reshape(raw_text)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 2. تصحيح اتجاه القراءة من اليمين لليسار
bidi_text = get_display(reshaped_text)

return bidi_text`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;🚀 النتيجة الحية (التطبيق العملي):&lt;/li&gt;
&lt;li&gt;لتسهيل الأمر على الطلاب والزملاء، قمت بدمج هذه الخوارزمية المعقدة في واجهة ويب بسيطة ضمن منصة طورتها مؤخراً.&lt;/li&gt;
&lt;li&gt;يمكنكم رؤية النتيجة الحية واختبار سرعة ودقة استخراج النصوص العربية (سواء من ملفات PDF أو الصور) عبر هذه الأداة المجانية:&lt;/li&gt;
&lt;li&gt;👉 &lt;a href="https://adawati.app/image-to-text/" rel="noopener noreferrer"&gt;أداة استخراج النصوص (OCR)&lt;/a&gt; - &lt;a href="https://adawati.app" rel="noopener noreferrer"&gt;منصة أدواتي&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;أتمنى أن تفيدكم هذه المقاربة في مشاريعكم القادمة. كيف تتعاملون أنتم مع ملفات الـ PDF العربية في تطبيقاتكم؟&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>showdev</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
