{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c92ad839",
   "metadata": {},
   "source": [
    "# Arabic AI Voice Agent for Saudi Labor Law  \n",
    "## Stage 02 — Data Preparation and Knowledge Base Construction\n",
    "\n",
    "This notebook implements the second stage of the project: preparing the legal and FAQ datasets for a Retrieval-Augmented Generation (RAG) system. The objective is to transform the raw scraped data into a clean, auditable, and evaluation-safe knowledge base that can later be indexed using embeddings and a vector database.\n",
    "\n",
    "A key methodological decision in this stage is to separate **legal completeness** from **retrieval safety**. All cleaned legal article records are preserved for auditability, including repealed articles and valid legal variants. However, only active legal articles are allowed into the experimental RAG knowledge base. This prevents the system from retrieving outdated or repealed legal provisions when answering users.\n",
    "\n",
    "**Inputs:** Raw scraping outputs stored under `saudi_labor_law_voice_agent_project/01_raw/`  \n",
    "**Outputs:** Clean datasets, safe RAG knowledge bases, evaluation datasets, chunk files, quality reports, and academic visualisations.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f3a9438",
   "metadata": {},
   "source": [
    "## Stage 00 — Project Setup\n",
    "\n",
    "This stage defines the project directory structure, imports the required Python libraries, and prepares the folders used throughout the data preparation pipeline.\n",
    "\n",
    "The setup cell should be executed once at the beginning of the notebook. It ensures that all subsequent outputs are stored in a consistent and reproducible project structure.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2b56daf7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Project folder is ready: C:\\Users\\PC\\Desktop\\data collection code\\saudi_labor_law_voice_agent_project\n",
      "Raw data folder: C:\\Users\\PC\\Desktop\\data collection code\\saudi_labor_law_voice_agent_project\\01_raw\n",
      "Figures folder: C:\\Users\\PC\\Desktop\\data collection code\\saudi_labor_law_voice_agent_project\\05_reports\\figures\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 00 - Project Setup\n",
    "# =========================================================\n",
    "\n",
    "# أول مرة فقط إذا احتجت:\n",
    "# !pip install pandas openpyxl numpy scikit-learn matplotlib\n",
    "# اختياري لتحسين عرض العربية في الرسوم:\n",
    "# !pip install arabic-reshaper python-bidi\n",
    "\n",
    "import os\n",
    "import re\n",
    "import json\n",
    "import shutil\n",
    "import hashlib\n",
    "import warnings\n",
    "from pathlib import Path\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "pd.set_option(\"display.max_colwidth\", 180)\n",
    "pd.set_option(\"display.max_columns\", 120)\n",
    "pd.set_option(\"display.width\", 160)\n",
    "\n",
    "PROJECT_DIR = Path(\"saudi_labor_law_voice_agent_project\")\n",
    "RAW_DIR = PROJECT_DIR / \"01_raw\"\n",
    "CLEAN_DIR = PROJECT_DIR / \"02_clean\"\n",
    "FINAL_DIR = PROJECT_DIR / \"03_final\"\n",
    "CHUNKS_DIR = PROJECT_DIR / \"04_chunks\"\n",
    "REPORTS_DIR = PROJECT_DIR / \"05_reports\"\n",
    "FIGURES_DIR = REPORTS_DIR / \"figures\"\n",
    "\n",
    "for folder in [RAW_DIR, CLEAN_DIR, FINAL_DIR, CHUNKS_DIR, REPORTS_DIR, FIGURES_DIR]:\n",
    "    folder.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# محاولة اختيار خط يدعم العربية إن كان متاحاً على الجهاز\n",
    "plt.rcParams[\"figure.dpi\"] = 120\n",
    "plt.rcParams[\"savefig.dpi\"] = 220\n",
    "plt.rcParams[\"axes.unicode_minus\"] = False\n",
    "plt.rcParams[\"font.family\"] = [\"Tahoma\", \"Arial\", \"DejaVu Sans\"]\n",
    "\n",
    "print(\"Project folder is ready:\", PROJECT_DIR.resolve())\n",
    "print(\"Raw data folder:\", RAW_DIR.resolve())\n",
    "print(\"Figures folder:\", FIGURES_DIR.resolve())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "380215da",
   "metadata": {},
   "source": [
    "## Stage 01 — Input File Configuration\n",
    "\n",
    "This stage defines the expected raw input files produced by the web scraping notebook. The files may be placed either in the same directory as this notebook or inside the project raw-data folder.\n",
    "\n",
    "The notebook expects two main sources:\n",
    "\n",
    "1. Saudi Labor Law articles scraped from the official HRSD source.\n",
    "2. Classified HRSD FAQ records containing questions, answers, and filter metadata.\n",
    "\n",
    "This step also defines the FAQ evaluation split ratio used later to prevent data leakage between indexing and evaluation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a3b7dac8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Labor articles file: saudi_labor_law_voice_agent_project\\01_raw\\saudi_labor_law_by_bab_articles.csv\n",
      "FAQ classified file: saudi_labor_law_voice_agent_project\\01_raw\\hrsd_faq_with_filters_classification.csv\n",
      "Raw files are available in: C:\\Users\\PC\\Desktop\\data collection code\\saudi_labor_law_voice_agent_project\\01_raw\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 01 - Input Files\n",
    "# =========================================================\n",
    "\n",
    "LABOR_ARTICLES_FILENAME = \"saudi_labor_law_by_bab_articles.csv\"\n",
    "FAQ_CLASSIFIED_FILENAME = \"hrsd_faq_with_filters_classification.csv\"\n",
    "\n",
    "# نسبة أسئلة FAQ التي سنتركها للتقييم لمنع تسريب البيانات في التجربة\n",
    "FAQ_EVAL_RATIO = 0.30\n",
    "RANDOM_SEED = 42\n",
    "\n",
    "\n",
    "def find_input_file(filename, search_roots=None):\n",
    "    \"\"\"Find a file in the final scraping output folder first, then fallback to common locations.\"\"\"\n",
    "    if search_roots is None:\n",
    "        search_roots = [\n",
    "            RAW_DIR,\n",
    "            PROJECT_DIR / \"01_raw\",\n",
    "            Path.cwd() / \"saudi_labor_law_voice_agent_project\" / \"01_raw\",\n",
    "            Path.cwd() / \"01_raw\",\n",
    "            Path.cwd(),\n",
    "            PROJECT_DIR,\n",
    "            Path.cwd() / \"data\",\n",
    "        ]\n",
    "\n",
    "    checked = []\n",
    "    for root in search_roots:\n",
    "        candidate = root / filename\n",
    "        checked.append(str(candidate))\n",
    "        if candidate.exists():\n",
    "            return candidate\n",
    "\n",
    "    # last resort: recursive search in current directory\n",
    "    for candidate in Path.cwd().glob(f\"**/{filename}\"):\n",
    "        if candidate.is_file():\n",
    "            return candidate\n",
    "\n",
    "    raise FileNotFoundError(\n",
    "        f\"لم أجد الملف: {filename}\\n\"\n",
    "        f\"ضع مخرجات مرحلة السحب داخل: {RAW_DIR.resolve()}\\n\\n\"\n",
    "        f\"المسارات التي تم فحصها:\\n\" + \"\\n\".join(checked)\n",
    "    )\n",
    "\n",
    "\n",
    "LABOR_ARTICLES_FILE = find_input_file(LABOR_ARTICLES_FILENAME)\n",
    "FAQ_CLASSIFIED_FILE = find_input_file(FAQ_CLASSIFIED_FILENAME)\n",
    "\n",
    "# نسخ نسخة من الملفات الخام داخل 01_raw للتوثيق، بدون إعادة سحب من الموقع\n",
    "for src in [LABOR_ARTICLES_FILE, FAQ_CLASSIFIED_FILE]:\n",
    "    dst = RAW_DIR / src.name\n",
    "    if src.resolve() != dst.resolve():\n",
    "        shutil.copy2(src, dst)\n",
    "\n",
    "print(\"Labor articles file:\", LABOR_ARTICLES_FILE)\n",
    "print(\"FAQ classified file:\", FAQ_CLASSIFIED_FILE)\n",
    "print(\"Raw files are available in:\", RAW_DIR.resolve())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62589c3a",
   "metadata": {},
   "source": [
    "## Stage 02 — Load Raw Scraped Data\n",
    "\n",
    "This stage loads the raw legal article dataset and the classified FAQ dataset exactly as produced by the scraping stage.\n",
    "\n",
    "The goal is not to transform the data yet, but to verify that the raw files are readable and that their initial shapes are available for later comparison during the cleaning and validation stages.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5369d760",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Articles raw shape: (249, 13)\n",
      "FAQ raw shape: (711, 10)\n",
      "\n",
      "Articles columns:\n",
      "['bab_order', 'bab_label', 'bab_title', 'fasl', 'article_title', 'article_number', 'article_number_label', 'article_number_int', 'article_text', 'source_url', 'searchable_text', 'text_len', 'article_status']\n",
      "\n",
      "FAQ columns:\n",
      "['faq_id', 'question', 'answer', 'beneficiaries', 'sector', 'subsite', 'page_number', 'page_url', 'source', 'searchable_text']\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>bab_order</th>\n",
       "      <th>bab_label</th>\n",
       "      <th>bab_title</th>\n",
       "      <th>fasl</th>\n",
       "      <th>article_title</th>\n",
       "      <th>article_number</th>\n",
       "      <th>article_number_label</th>\n",
       "      <th>article_number_int</th>\n",
       "      <th>article_text</th>\n",
       "      <th>source_url</th>\n",
       "      <th>searchable_text</th>\n",
       "      <th>text_len</th>\n",
       "      <th>article_status</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الأول</td>\n",
       "      <td>المادة الأولى:</td>\n",
       "      <td>الأولى</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>يسمى هذا النظام نظام العمل.</td>\n",
       "      <td>https://www.hrsd.gov.sa/node/5575978</td>\n",
       "      <td>الباب الأول - التعريفات / الأحكام العامة - الفصل الأول - المادة الأولى: - يسمى هذا النظام نظام العمل.</td>\n",
       "      <td>27</td>\n",
       "      <td>active</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الأول</td>\n",
       "      <td>المادة الثانية :</td>\n",
       "      <td>الثانية</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق خلاف ذلك: -الوزارة: وزارة الموارد البشرية والتنمية الاجتماعية. -الوزير: وزي...</td>\n",
       "      <td>https://www.hrsd.gov.sa/node/5575978</td>\n",
       "      <td>الباب الأول - التعريفات / الأحكام العامة - الفصل الأول - المادة الثانية : - يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق...</td>\n",
       "      <td>3519</td>\n",
       "      <td>active</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة الثالثة:</td>\n",
       "      <td>الثالثة</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطنون متساوون في حق العمل دون أي تمييز على أساس الجنس أو الإعاقة أو السن أو أي ...</td>\n",
       "      <td>https://www.hrsd.gov.sa/node/5575978</td>\n",
       "      <td>الباب الأول - التعريفات / الأحكام العامة - الفصل الثاني - المادة الثالثة: - العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطن...</td>\n",
       "      <td>258</td>\n",
       "      <td>active</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   bab_order    bab_label                   bab_title          fasl     article_title article_number article_number_label  article_number_int  \\\n",
       "0          1  الباب الأول  التعريفات / الأحكام العامة   الفصل الأول    المادة الأولى:         الأولى                    1                   1   \n",
       "1          1  الباب الأول  التعريفات / الأحكام العامة   الفصل الأول  المادة الثانية :        الثانية                    2                   2   \n",
       "2          1  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة الثالثة:        الثالثة                    3                   3   \n",
       "\n",
       "                                                                                                                                                                          article_text  \\\n",
       "0                                                                                                                                                          يسمى هذا النظام نظام العمل.   \n",
       "1  يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق خلاف ذلك: -الوزارة: وزارة الموارد البشرية والتنمية الاجتماعية. -الوزير: وزي...   \n",
       "2  العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطنون متساوون في حق العمل دون أي تمييز على أساس الجنس أو الإعاقة أو السن أو أي ...   \n",
       "\n",
       "                             source_url  \\\n",
       "0  https://www.hrsd.gov.sa/node/5575978   \n",
       "1  https://www.hrsd.gov.sa/node/5575978   \n",
       "2  https://www.hrsd.gov.sa/node/5575978   \n",
       "\n",
       "                                                                                                                                                                       searchable_text  \\\n",
       "0                                                                                الباب الأول - التعريفات / الأحكام العامة - الفصل الأول - المادة الأولى: - يسمى هذا النظام نظام العمل.   \n",
       "1  الباب الأول - التعريفات / الأحكام العامة - الفصل الأول - المادة الثانية : - يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق...   \n",
       "2  الباب الأول - التعريفات / الأحكام العامة - الفصل الثاني - المادة الثالثة: - العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطن...   \n",
       "\n",
       "   text_len article_status  \n",
       "0        27         active  \n",
       "1      3519         active  \n",
       "2       258         active  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>faq_id</th>\n",
       "      <th>question</th>\n",
       "      <th>answer</th>\n",
       "      <th>beneficiaries</th>\n",
       "      <th>sector</th>\n",
       "      <th>subsite</th>\n",
       "      <th>page_number</th>\n",
       "      <th>page_url</th>\n",
       "      <th>source</th>\n",
       "      <th>searchable_text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟</td>\n",
       "      <td>تقدم الوزارة خدمة التوقيع الالكتروني في اطار ادارة وتوثيق عقود العمل عبر منصة \"قوى\" يمكن للمنشآت انشاء وتوثيق وانهاء عقود العمل للموظفين بشكل الكرتوني بالكامل.</td>\n",
       "      <td>أصحاب عمل | أفراد | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع العمل</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "      <td>1</td>\n",
       "      <td>https://www.hrsd.gov.sa/contact-us/faq</td>\n",
       "      <td>HRSD FAQ</td>\n",
       "      <td>التصنيف: أصحاب عمل | أفراد | العمالة المنزلية | كبار السن قطاع العمل مركز الرياض للسياسات السلوكية السؤال: هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟ الإ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟</td>\n",
       "      <td>الدخول إلى “مهامي” ← اختيار مهمة طلب مراجعة ← تعديل البيانات ← إعادة الإرسال.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "      <td>1</td>\n",
       "      <td>https://www.hrsd.gov.sa/contact-us/faq</td>\n",
       "      <td>HRSD FAQ</td>\n",
       "      <td>التصنيف: التخصصات الاجتماعية | العمالة المنزلية | كبار السن قطاع التنمية الاجتماعية مركز الرياض للسياسات السلوكية السؤال: ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟ الإجابة: الدخول...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>ماذا يحدث بعد إرسال الطلب؟</td>\n",
       "      <td>يتم تحويل الطلب إلى اللجنة للمراجعة ويتم إشعار المتقدم بحالة الطلب.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "      <td>1</td>\n",
       "      <td>https://www.hrsd.gov.sa/contact-us/faq</td>\n",
       "      <td>HRSD FAQ</td>\n",
       "      <td>التصنيف: التخصصات الاجتماعية | العمالة المنزلية | كبار السن قطاع التنمية الاجتماعية مركز الرياض للسياسات السلوكية السؤال: ماذا يحدث بعد إرسال الطلب؟ الإجابة: يتم تحويل الطلب إل...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   faq_id                                                           question  \\\n",
       "0       1  هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟   \n",
       "1       2                             ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟   \n",
       "2       3                                         ماذا يحدث بعد إرسال الطلب؟   \n",
       "\n",
       "                                                                                                                                                            answer  \\\n",
       "0  تقدم الوزارة خدمة التوقيع الالكتروني في اطار ادارة وتوثيق عقود العمل عبر منصة \"قوى\" يمكن للمنشآت انشاء وتوثيق وانهاء عقود العمل للموظفين بشكل الكرتوني بالكامل.   \n",
       "1                                                                                    الدخول إلى “مهامي” ← اختيار مهمة طلب مراجعة ← تعديل البيانات ← إعادة الإرسال.   \n",
       "2                                                                                              يتم تحويل الطلب إلى اللجنة للمراجعة ويتم إشعار المتقدم بحالة الطلب.   \n",
       "\n",
       "                                        beneficiaries                   sector                        subsite  page_number  \\\n",
       "0    أصحاب عمل | أفراد | العمالة المنزلية | كبار السن               قطاع العمل  مركز الرياض للسياسات السلوكية            1   \n",
       "1  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية            1   \n",
       "2  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية            1   \n",
       "\n",
       "                                 page_url    source  \\\n",
       "0  https://www.hrsd.gov.sa/contact-us/faq  HRSD FAQ   \n",
       "1  https://www.hrsd.gov.sa/contact-us/faq  HRSD FAQ   \n",
       "2  https://www.hrsd.gov.sa/contact-us/faq  HRSD FAQ   \n",
       "\n",
       "                                                                                                                                                                       searchable_text  \n",
       "0  التصنيف: أصحاب عمل | أفراد | العمالة المنزلية | كبار السن قطاع العمل مركز الرياض للسياسات السلوكية السؤال: هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟ الإ...  \n",
       "1  التصنيف: التخصصات الاجتماعية | العمالة المنزلية | كبار السن قطاع التنمية الاجتماعية مركز الرياض للسياسات السلوكية السؤال: ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟ الإجابة: الدخول...  \n",
       "2  التصنيف: التخصصات الاجتماعية | العمالة المنزلية | كبار السن قطاع التنمية الاجتماعية مركز الرياض للسياسات السلوكية السؤال: ماذا يحدث بعد إرسال الطلب؟ الإجابة: يتم تحويل الطلب إل...  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 02 - Load Scraped Data\n",
    "# =========================================================\n",
    "\n",
    "df_articles_raw = pd.read_csv(LABOR_ARTICLES_FILE, encoding=\"utf-8-sig\")\n",
    "df_faq_raw = pd.read_csv(FAQ_CLASSIFIED_FILE, encoding=\"utf-8-sig\")\n",
    "\n",
    "print(\"Articles raw shape:\", df_articles_raw.shape)\n",
    "print(\"FAQ raw shape:\", df_faq_raw.shape)\n",
    "\n",
    "print(\"\\nArticles columns:\")\n",
    "print(list(df_articles_raw.columns))\n",
    "\n",
    "print(\"\\nFAQ columns:\")\n",
    "print(list(df_faq_raw.columns))\n",
    "\n",
    "display(df_articles_raw.head(3))\n",
    "display(df_faq_raw.head(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0eb6719",
   "metadata": {},
   "source": [
    "## Stage 03 — Arabic Text Cleaning Utilities\n",
    "\n",
    "This stage defines reusable helper functions for cleaning Arabic legal and FAQ text.\n",
    "\n",
    "The cleaning process is designed to be conservative: it removes noise such as extra spaces, unnecessary symbols, and formatting artefacts while preserving the legal meaning of the original text. A separate indexing-friendly version of the text is later created for retrieval purposes.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2220cf48",
   "metadata": {},
   "outputs": [],
   "source": [
    "# =========================================================\n",
    "# Stage 03 - Arabic Text Cleaning Helpers\n",
    "# =========================================================\n",
    "\n",
    "ARABIC_DIACRITICS = re.compile(r\"[\\u0617-\\u061A\\u064B-\\u0652]\")\n",
    "TATWEEL = \"\\u0640\"\n",
    "\n",
    "\n",
    "def clean_basic_text(text):\n",
    "    \"\"\"\n",
    "    تنظيف محافظ لا يغيّر معنى النص القانوني.\n",
    "    نستخدمه للنصوص الأصلية والأعمدة العامة.\n",
    "    \"\"\"\n",
    "    if pd.isna(text):\n",
    "        return \"\"\n",
    "    text = str(text)\n",
    "    text = text.replace(\"\\xa0\", \" \")\n",
    "    text = text.replace(\"\\u200f\", \" \")\n",
    "    text = text.replace(\"\\u200e\", \" \")\n",
    "    text = text.replace(\"\\ufeff\", \" \")\n",
    "    text = re.sub(r\"\\s+\", \" \", text)\n",
    "    return text.strip()\n",
    "\n",
    "\n",
    "def normalize_arabic_for_search(text):\n",
    "    \"\"\"\n",
    "    نسخة مخصصة للفهرسة/البحث فقط، وليست بديلاً عن النص القانوني الأصلي.\n",
    "    \"\"\"\n",
    "    text = clean_basic_text(text)\n",
    "    text = text.replace(TATWEEL, \"\")\n",
    "    text = ARABIC_DIACRITICS.sub(\"\", text)\n",
    "    text = re.sub(\"[إأآا]\", \"ا\", text)\n",
    "    text = re.sub(\"ى\", \"ي\", text)\n",
    "    text = re.sub(\"ؤ\", \"و\", text)\n",
    "    text = re.sub(\"ئ\", \"ي\", text)\n",
    "    text = re.sub(\"ة\", \"ه\", text)\n",
    "    text = re.sub(r\"[^\\u0600-\\u06FFa-zA-Z0-9\\s،؛؟:.,()\\-/%]\", \" \", text)\n",
    "    text = re.sub(r\"\\s+\", \" \", text)\n",
    "    return text.strip()\n",
    "\n",
    "\n",
    "def safe_col(df, col, default=\"\"):\n",
    "    \"\"\"Create missing column if not found.\"\"\"\n",
    "    if col not in df.columns:\n",
    "        df[col] = default\n",
    "    return df\n",
    "\n",
    "\n",
    "def make_hash(*values):\n",
    "    \"\"\"Stable id for records/chunks.\"\"\"\n",
    "    raw = \"|||\".join(clean_basic_text(v) for v in values)\n",
    "    return hashlib.sha256(raw.encode(\"utf-8\")).hexdigest()\n",
    "\n",
    "\n",
    "def deterministic_split_by_hash(value, eval_ratio=0.20):\n",
    "    \"\"\"\n",
    "    Deterministic split without random leakage.\n",
    "    Returns True if record should go to evaluation.\n",
    "    \"\"\"\n",
    "    h = hashlib.md5(str(value).encode(\"utf-8\")).hexdigest()\n",
    "    bucket = int(h[:8], 16) / 0xFFFFFFFF\n",
    "    return bucket < eval_ratio"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5bb3eee2",
   "metadata": {},
   "source": [
    "## Stage 04 — Clean Saudi Labor Law Articles\n",
    "\n",
    "This stage cleans the legal article dataset while preserving legal auditability.\n",
    "\n",
    "Repealed articles are **not deleted** at this stage. Instead, they are explicitly labelled using the `article_status` field. This design keeps the cleaned legal dataset complete for documentation and audit purposes, while allowing later stages to safely exclude repealed provisions from RAG indexing.\n",
    "\n",
    "The cleaned legal dataset therefore supports two goals:\n",
    "\n",
    "1. Maintaining a complete legal audit dataset.\n",
    "2. Building a safe retrieval knowledge base using active articles only.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a049af89",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Articles raw rows: 249\n",
      "Articles after empty-text filter: 249\n",
      "Legal article records after true deduplication: 249\n",
      "Unique numeric article numbers: 245 | max: 245\n",
      "Missing numeric article numbers: []\n",
      "True duplicated article labels: 0\n",
      "Repeated numeric numbers, often legal 'مكرر' articles: 4\n",
      "Empty article_text: 0\n",
      "\n",
      "Article status distribution:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>article_status</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>active</th>\n",
       "      <td>211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>repealed</th>\n",
       "      <td>38</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                count\n",
       "article_status       \n",
       "active            211\n",
       "repealed           38"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Short non-repealed articles. This should usually contain only very short valid articles such as Article 1:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>article_number_label</th>\n",
       "      <th>article_title</th>\n",
       "      <th>article_text</th>\n",
       "      <th>text_len</th>\n",
       "      <th>article_status</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>المادة الأولى:</td>\n",
       "      <td>يسمى هذا النظام نظام العمل.</td>\n",
       "      <td>27</td>\n",
       "      <td>active</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  article_number_label   article_title                 article_text  text_len article_status\n",
       "0                    1  المادة الأولى:  يسمى هذا النظام نظام العمل.        27         active"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>bab_label</th>\n",
       "      <th>bab_title</th>\n",
       "      <th>fasl</th>\n",
       "      <th>article_title</th>\n",
       "      <th>article_number_label</th>\n",
       "      <th>article_status</th>\n",
       "      <th>article_text</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الأول</td>\n",
       "      <td>المادة الأولى:</td>\n",
       "      <td>1</td>\n",
       "      <td>active</td>\n",
       "      <td>يسمى هذا النظام نظام العمل.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الأول</td>\n",
       "      <td>المادة الثانية :</td>\n",
       "      <td>2</td>\n",
       "      <td>active</td>\n",
       "      <td>يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق خلاف ذلك: -الوزارة: وزارة الموارد البشرية والتنمية الاجتماعية. -الوزير: وزي...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة الثالثة:</td>\n",
       "      <td>3</td>\n",
       "      <td>active</td>\n",
       "      <td>العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطنون متساوون في حق العمل دون أي تمييز على أساس الجنس أو الإعاقة أو السن أو أي ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة الرابعة:</td>\n",
       "      <td>4</td>\n",
       "      <td>active</td>\n",
       "      <td>يجب على صاحب العمل والعامل عند تطبيق أحكام هذا النظام الإلتزام بمقتضيات أحكام الشريعة الإسلامية .</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة الخامسة:</td>\n",
       "      <td>5</td>\n",
       "      <td>active</td>\n",
       "      <td>تسري أحكام هذا النظام على الآتي: كل عقد عمل يلتزم بمقتضاه أي شخص بالعمل لمصلحة صاحب عمل وتحت إدارته أو إشرافه ؛ مقابل أجر. عمال الحكومة والهيئات والمؤسسات العامة ، بمن فيهم الذ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة السادسة:</td>\n",
       "      <td>6</td>\n",
       "      <td>active</td>\n",
       "      <td>تسري على العامل العرضي والموسمي والمؤقت الأحكام الخاصة بالواجبات وقواعد التأديب ، والحد الأقصى لساعات العمل ، وفترات الراحة اليومية والراحة الأسبوعية ، والتشغيل الإضافي ، والعط...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة السابعة :</td>\n",
       "      <td>7</td>\n",
       "      <td>active</td>\n",
       "      <td>1- يستثنى من تطبيق أحكام هذا النظام كل من: أ‌- أفراد أسرة صاحب العمل، وهم زوجه وأصوله وفروعه الذين يعملون في المنشأة التي لا تضم سواهم. ب‌- لاعبو الأندية والاتحادات الرياضية وم...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة الثامنة:</td>\n",
       "      <td>8</td>\n",
       "      <td>active</td>\n",
       "      <td>يبطل كل شرط يخالف أحكام هذا النظام ، ويبطل كل إبراء ، أو مصالحة عن الحقوق الناشئة للعامل بموجب هذا النظام ، أثناء سريان عقد العمل ، ما لم يكن أكثر فائدة للعامل.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة التاسعة:</td>\n",
       "      <td>9</td>\n",
       "      <td>active</td>\n",
       "      <td>اللغة العربية هي الواجبة الإستعمال في البيانات والسجلات والملفات وعقود العمل وغيرها مما هو منصوص عليه في هذا النظام ، أو في أي قرار صادر تطبيقاً لأحكامه ، وكذلك التعليمات التي ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>الباب الأول</td>\n",
       "      <td>التعريفات / الأحكام العامة</td>\n",
       "      <td>الفصل الثاني</td>\n",
       "      <td>المادة العاشرة:</td>\n",
       "      <td>10</td>\n",
       "      <td>active</td>\n",
       "      <td>تحسب جميع المدد والمواعيد المنصوص عليها في هذا النظام بالتقويم الهجري ، مالم ينص في عقد العمل أو لائحة تنظيم العمل على خلاف ذلك .</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     bab_label                   bab_title          fasl     article_title article_number_label article_status  \\\n",
       "0  الباب الأول  التعريفات / الأحكام العامة   الفصل الأول    المادة الأولى:                    1         active   \n",
       "1  الباب الأول  التعريفات / الأحكام العامة   الفصل الأول  المادة الثانية :                    2         active   \n",
       "2  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة الثالثة:                    3         active   \n",
       "3  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة الرابعة:                    4         active   \n",
       "4  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة الخامسة:                    5         active   \n",
       "5  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة السادسة:                    6         active   \n",
       "6  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني  المادة السابعة :                    7         active   \n",
       "7  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة الثامنة:                    8         active   \n",
       "8  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة التاسعة:                    9         active   \n",
       "9  الباب الأول  التعريفات / الأحكام العامة  الفصل الثاني   المادة العاشرة:                   10         active   \n",
       "\n",
       "                                                                                                                                                                          article_text  \n",
       "0                                                                                                                                                          يسمى هذا النظام نظام العمل.  \n",
       "1  يقصد بالألفاظ والعبارات الآتية – أينما وردت في هذا النظام – المعاني المبينة أمامها ما لم يقتض السياق خلاف ذلك: -الوزارة: وزارة الموارد البشرية والتنمية الاجتماعية. -الوزير: وزي...  \n",
       "2  العمل حق للمواطن ، لا يجوز لغيره ممارسته إلا بعد توافر الشروط المنصوص عليها في هذا النظام ، والمواطنون متساوون في حق العمل دون أي تمييز على أساس الجنس أو الإعاقة أو السن أو أي ...  \n",
       "3                                                                                    يجب على صاحب العمل والعامل عند تطبيق أحكام هذا النظام الإلتزام بمقتضيات أحكام الشريعة الإسلامية .  \n",
       "4  تسري أحكام هذا النظام على الآتي: كل عقد عمل يلتزم بمقتضاه أي شخص بالعمل لمصلحة صاحب عمل وتحت إدارته أو إشرافه ؛ مقابل أجر. عمال الحكومة والهيئات والمؤسسات العامة ، بمن فيهم الذ...  \n",
       "5  تسري على العامل العرضي والموسمي والمؤقت الأحكام الخاصة بالواجبات وقواعد التأديب ، والحد الأقصى لساعات العمل ، وفترات الراحة اليومية والراحة الأسبوعية ، والتشغيل الإضافي ، والعط...  \n",
       "6  1- يستثنى من تطبيق أحكام هذا النظام كل من: أ‌- أفراد أسرة صاحب العمل، وهم زوجه وأصوله وفروعه الذين يعملون في المنشأة التي لا تضم سواهم. ب‌- لاعبو الأندية والاتحادات الرياضية وم...  \n",
       "7                     يبطل كل شرط يخالف أحكام هذا النظام ، ويبطل كل إبراء ، أو مصالحة عن الحقوق الناشئة للعامل بموجب هذا النظام ، أثناء سريان عقد العمل ، ما لم يكن أكثر فائدة للعامل.  \n",
       "8  اللغة العربية هي الواجبة الإستعمال في البيانات والسجلات والملفات وعقود العمل وغيرها مما هو منصوص عليه في هذا النظام ، أو في أي قرار صادر تطبيقاً لأحكامه ، وكذلك التعليمات التي ...  \n",
       "9                                                    تحسب جميع المدد والمواعيد المنصوص عليها في هذا النظام بالتقويم الهجري ، مالم ينص في عقد العمل أو لائحة تنظيم العمل على خلاف ذلك .  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 04 - Clean Legal Articles\n",
    "# الاحتفاظ بالمواد الملغاة ومواد \"مكرر\" لأنها مهمة قانونياً\n",
    "# =========================================================\n",
    "\n",
    "df_articles = df_articles_raw.copy()\n",
    "\n",
    "required_article_cols = [\n",
    "    \"bab_order\", \"bab_label\", \"bab_title\", \"fasl\",\n",
    "    \"article_title\", \"article_number\", \"article_number_label\",\n",
    "    \"article_number_int\", \"article_text\", \"source_url\"\n",
    "]\n",
    "\n",
    "for col in required_article_cols:\n",
    "    df_articles = safe_col(df_articles, col, \"\")\n",
    "\n",
    "# تنظيف محافظ للأعمدة النصية\n",
    "for col in required_article_cols:\n",
    "    df_articles[col] = df_articles[col].apply(clean_basic_text)\n",
    "\n",
    "# إذا لم يكن article_number_label متوفراً بشكل جيد، نستخدم article_number كبديل\n",
    "df_articles[\"article_number_label\"] = np.where(\n",
    "    df_articles[\"article_number_label\"].astype(str).str.strip().eq(\"\"),\n",
    "    df_articles[\"article_number\"],\n",
    "    df_articles[\"article_number_label\"],\n",
    ")\n",
    "\n",
    "# تحويل الرقم إلى قيمة رقمية مع الاحتفاظ بالنسخة النصية القانونية في article_number_label\n",
    "df_articles[\"article_number_int\"] = pd.to_numeric(df_articles[\"article_number_int\"], errors=\"coerce\")\n",
    "\n",
    "# تنظيف نص المادة مع إزالة التطويل فقط، بدون حذف المواد القصيرة\n",
    "before_raw_rows = len(df_articles)\n",
    "df_articles[\"article_text\"] = (\n",
    "    df_articles[\"article_text\"]\n",
    "    .fillna(\"\")\n",
    "    .astype(str)\n",
    "    .str.replace(r\"[ـ]+\", \"\", regex=True)\n",
    "    .str.replace(r\"\\s+\", \" \", regex=True)\n",
    "    .str.strip()\n",
    ")\n",
    "\n",
    "df_articles[\"text_len\"] = df_articles[\"article_text\"].str.len()\n",
    "\n",
    "# تصنيف حالة المادة\n",
    "df_articles[\"article_status\"] = df_articles[\"article_text\"].apply(\n",
    "    lambda x: \"repealed\" if (\"ملغاة\" in x or \"ملغى\" in x) else \"active\"\n",
    ")\n",
    "\n",
    "# حذف الصفوف الفارغة فقط، وليس المواد القصيرة مثل \"ملغاة\"\n",
    "df_articles = df_articles[df_articles[\"article_text\"].str.len() > 0].copy()\n",
    "before_dedup_rows = len(df_articles)\n",
    "\n",
    "# إزالة التكرار الحقيقي حسب article_number_label، مع الاحتفاظ بأطول نص لنفس المادة إن تكرر نفس label فعلاً\n",
    "df_articles = (\n",
    "    df_articles\n",
    "    .sort_values([\"article_number_label\", \"text_len\"], ascending=[True, False])\n",
    "    .drop_duplicates(subset=[\"article_number_label\"], keep=\"first\")\n",
    "    .sort_values([\"article_number_int\", \"article_number_label\"], na_position=\"last\")\n",
    "    .reset_index(drop=True)\n",
    ")\n",
    "\n",
    "# Metadata\n",
    "\n",
    "df_articles[\"source_type\"] = \"legal_article\"\n",
    "df_articles[\"source_name\"] = \"نظام العمل السعودي\"\n",
    "df_articles[\"legal_category\"] = df_articles[\"bab_title\"].replace(\"\", np.nan).fillna(\"نظام العمل\")\n",
    "\n",
    "df_articles[\"document_unit_id\"] = df_articles.apply(\n",
    "    lambda r: make_hash(\n",
    "        r[\"source_type\"],\n",
    "        r[\"article_number_label\"],\n",
    "        r[\"article_title\"],\n",
    "        r[\"article_text\"]\n",
    "    ),\n",
    "    axis=1\n",
    ")\n",
    "\n",
    "df_articles[\"text_for_indexing\"] = df_articles.apply(\n",
    "    lambda r: clean_basic_text(\n",
    "        f\"المصدر: {r['source_name']}\\n\"\n",
    "        f\"{r['bab_label']} - {r['bab_title']}\\n\"\n",
    "        f\"{r['fasl']}\\n\"\n",
    "        f\"{r['article_title']}\\n\"\n",
    "        f\"رقم المادة: {r['article_number_label']}\\n\"\n",
    "        f\"حالة المادة: {r['article_status']}\\n\"\n",
    "        f\"النص: {r['article_text']}\"\n",
    "    ),\n",
    "    axis=1\n",
    ")\n",
    "\n",
    "df_articles[\"normalized_text\"] = df_articles[\"text_for_indexing\"].apply(normalize_arabic_for_search)\n",
    "\n",
    "# حفظ النسخة النظيفة\n",
    "\n",
    "df_articles.to_csv(CLEAN_DIR / \"clean_labor_law_articles.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "df_articles.to_excel(CLEAN_DIR / \"clean_labor_law_articles.xlsx\", index=False)\n",
    "\n",
    "# فحوصات مهمة\n",
    "valid_nums = df_articles[\"article_number_int\"].dropna().astype(int)\n",
    "nums = set(valid_nums)\n",
    "max_num = max(nums) if nums else 0\n",
    "missing_numeric_articles = [n for n in range(1, max_num + 1) if n not in nums]\n",
    "true_duplicate_labels = int(df_articles[\"article_number_label\"].duplicated().sum())\n",
    "repeated_numeric_numbers = int(df_articles[\"article_number_int\"].duplicated().sum())\n",
    "\n",
    "print(\"Articles raw rows:\", before_raw_rows)\n",
    "print(\"Articles after empty-text filter:\", before_dedup_rows)\n",
    "print(\"Legal article records after true deduplication:\", len(df_articles))\n",
    "print(\"Unique numeric article numbers:\", len(nums), \"| max:\", max_num)\n",
    "print(\"Missing numeric article numbers:\", missing_numeric_articles)\n",
    "print(\"True duplicated article labels:\", true_duplicate_labels)\n",
    "print(\"Repeated numeric numbers, often legal 'مكرر' articles:\", repeated_numeric_numbers)\n",
    "print(\"Empty article_text:\", int((df_articles[\"article_text\"].astype(str).str.strip() == \"\").sum()))\n",
    "\n",
    "print(\"\\nArticle status distribution:\")\n",
    "display(df_articles[\"article_status\"].value_counts().to_frame(\"count\"))\n",
    "\n",
    "print(\"\\nShort non-repealed articles. This should usually contain only very short valid articles such as Article 1:\")\n",
    "display(\n",
    "    df_articles[\n",
    "        (df_articles[\"text_len\"] < 30) &\n",
    "        (df_articles[\"article_status\"] != \"repealed\")\n",
    "    ][[\"article_number_label\", \"article_title\", \"article_text\", \"text_len\", \"article_status\"]]\n",
    ")\n",
    "\n",
    "display(df_articles[[\n",
    "    \"bab_label\", \"bab_title\", \"fasl\", \"article_title\",\n",
    "    \"article_number_label\", \"article_status\", \"article_text\"\n",
    "]].head(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d1bf89e",
   "metadata": {},
   "source": [
    "## Stage 04.1 — Separate Active and Repealed Legal Articles\n",
    "\n",
    "This stage separates the cleaned legal dataset into active articles and repealed articles.\n",
    "\n",
    "Active articles are allowed to enter the RAG indexing knowledge base, while repealed articles are archived separately and excluded from retrieval. This separation is essential in a legal RAG system because retrieving repealed provisions may lead to outdated or misleading answers.\n",
    "\n",
    "The archived repealed articles remain available for transparency, documentation, and future legal review, but they are not used as retrievable knowledge in the experimental system.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4745f880",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "إجمالي مواد النظام في ملف التدقيق: 249\n",
      "المواد الفعالة المستخدمة في RAG: 211\n",
      "المواد الملغاة المحفوظة كأرشيف فقط: 38\n",
      "مواد ملغاة داخل مواد RAG الفعالة: 0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>dataset</th>\n",
       "      <th>count</th>\n",
       "      <th>rag_policy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>All legal articles - cleaned audit dataset</td>\n",
       "      <td>249</td>\n",
       "      <td>retained_for_audit</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Active legal articles - allowed for RAG indexing</td>\n",
       "      <td>211</td>\n",
       "      <td>indexed</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Repealed legal articles - archive only, not indexed</td>\n",
       "      <td>38</td>\n",
       "      <td>excluded_from_index</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                               dataset  count           rag_policy\n",
       "0           All legal articles - cleaned audit dataset    249   retained_for_audit\n",
       "1     Active legal articles - allowed for RAG indexing    211              indexed\n",
       "2  Repealed legal articles - archive only, not indexed     38  excluded_from_index"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved active-only articles: saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_active_only_for_rag.csv\n",
      "Saved repealed archive: saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_repealed_archive_not_indexed.csv\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 04.1 - Separate Active and Repealed Legal Articles\n",
    "# فصل المواد الفعالة عن المواد الملغاة\n",
    "# =========================================================\n",
    "\n",
    "# جميع المواد محفوظة في df_articles لأغراض التدقيق والتحليل.\n",
    "# لكن الاسترجاع RAG يجب أن يستخدم المواد الفعالة فقط.\n",
    "\n",
    "df_articles_active = df_articles[df_articles[\"article_status\"] == \"active\"].copy()\n",
    "df_articles_repealed = df_articles[df_articles[\"article_status\"] == \"repealed\"].copy()\n",
    "\n",
    "# وسم الاستخدام داخل المشروع\n",
    "df_articles_active[\"rag_usage\"] = \"indexing_allowed_active_law\"\n",
    "df_articles_repealed[\"rag_usage\"] = \"archive_only_not_indexed\"\n",
    "\n",
    "# حفظ الملفات المنفصلة\n",
    "active_articles_path = CLEAN_DIR / \"clean_labor_law_articles_active_only_for_rag.csv\"\n",
    "repealed_articles_path = CLEAN_DIR / \"clean_labor_law_articles_repealed_archive_not_indexed.csv\"\n",
    "\n",
    "df_articles_active.to_csv(active_articles_path, index=False, encoding=\"utf-8-sig\")\n",
    "df_articles_active.to_excel(CLEAN_DIR / \"clean_labor_law_articles_active_only_for_rag.xlsx\", index=False)\n",
    "\n",
    "df_articles_repealed.to_csv(repealed_articles_path, index=False, encoding=\"utf-8-sig\")\n",
    "df_articles_repealed.to_excel(CLEAN_DIR / \"clean_labor_law_articles_repealed_archive_not_indexed.xlsx\", index=False)\n",
    "\n",
    "# فحص سلامة الفصل\n",
    "split_audit = pd.DataFrame({\n",
    "    \"dataset\": [\n",
    "        \"All legal articles - cleaned audit dataset\",\n",
    "        \"Active legal articles - allowed for RAG indexing\",\n",
    "        \"Repealed legal articles - archive only, not indexed\"\n",
    "    ],\n",
    "    \"count\": [\n",
    "        len(df_articles),\n",
    "        len(df_articles_active),\n",
    "        len(df_articles_repealed)\n",
    "    ],\n",
    "    \"rag_policy\": [\n",
    "        \"retained_for_audit\",\n",
    "        \"indexed\",\n",
    "        \"excluded_from_index\"\n",
    "    ]\n",
    "})\n",
    "\n",
    "split_audit.to_csv(REPORTS_DIR / \"legal_article_rag_policy_split.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "split_audit.to_excel(REPORTS_DIR / \"legal_article_rag_policy_split.xlsx\", index=False)\n",
    "\n",
    "print(\"إجمالي مواد النظام في ملف التدقيق:\", len(df_articles))\n",
    "print(\"المواد الفعالة المستخدمة في RAG:\", len(df_articles_active))\n",
    "print(\"المواد الملغاة المحفوظة كأرشيف فقط:\", len(df_articles_repealed))\n",
    "print(\"مواد ملغاة داخل مواد RAG الفعالة:\", int((df_articles_active[\"article_status\"] == \"repealed\").sum()))\n",
    "\n",
    "display(split_audit)\n",
    "\n",
    "print(\"Saved active-only articles:\", active_articles_path)\n",
    "print(\"Saved repealed archive:\", repealed_articles_path)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2e67c5d",
   "metadata": {},
   "source": [
    "## Stage 05 — Clean Classified HRSD FAQ Records\n",
    "\n",
    "This stage cleans the classified FAQ dataset extracted from the HRSD website.\n",
    "\n",
    "Each FAQ record is treated as a question-answer unit enriched with metadata such as beneficiary type, sector, subsite, and source URL. The cleaned FAQ records are later divided into indexing and evaluation subsets to ensure that the retrieval evaluation is performed on unseen questions.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "763693cf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FAQ raw rows: 711\n",
      "FAQ after empty filter: 703\n",
      "FAQ after dedup: 703\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>question</th>\n",
       "      <th>answer</th>\n",
       "      <th>beneficiaries</th>\n",
       "      <th>sector</th>\n",
       "      <th>subsite</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟</td>\n",
       "      <td>تقدم الوزارة خدمة التوقيع الالكتروني في اطار ادارة وتوثيق عقود العمل عبر منصة \"قوى\" يمكن للمنشآت انشاء وتوثيق وانهاء عقود العمل للموظفين بشكل الكرتوني بالكامل.</td>\n",
       "      <td>أصحاب عمل | أفراد | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع العمل</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟</td>\n",
       "      <td>الدخول إلى “مهامي” ← اختيار مهمة طلب مراجعة ← تعديل البيانات ← إعادة الإرسال.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>ماذا يحدث بعد إرسال الطلب؟</td>\n",
       "      <td>يتم تحويل الطلب إلى اللجنة للمراجعة ويتم إشعار المتقدم بحالة الطلب.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>كيف أقدم طلب تعديل فئة مهنية؟</td>\n",
       "      <td>من خلال تسجيل الدخول ← الخدمات ← اختيار “طلب تعديل الفئة المهنية” ← تعبئة النموذج ← إرسال الطلب.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>ما متطلبات التقديم؟</td>\n",
       "      <td>أن يكون المتقدم حاصل على ترخيص سابق.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>من يمكنه التقديم على خدمة تعديل الفئة المهنية؟</td>\n",
       "      <td>الممارس الحاصل على ترخيص من خلال خدمة التسجيل والتصنيف المهني.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td></td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>هل يمكن للمتقدم أن يحصل على أكثر من تصنيف وبالتالي أكثر من رخصة؟</td>\n",
       "      <td>نعم، يمكن للمتقدم الحصول على أكثر من رخصة إذا كان يحمل مؤهلات أو دورات أو خبرات تؤهله لذلك.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>إذا رفض طلب التسجيل والتصنيف هل يحق لي استرداد رسوم الخدمة؟</td>\n",
       "      <td>نعم، يحق لك استرداد رسوم خدمة التسجيل والتصنيف إذا رفض الطلب.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>ماذا يحدث في حال رفض الطلب؟</td>\n",
       "      <td>يمكنك الاطلاع على سبب الرفض من خلال تفاصيل الطلب، ثم التقديم بطلب جديد بعد معالجة الأسباب.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td></td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>هل يمكن إلغاء الفاتورة؟</td>\n",
       "      <td>نعم، يمكن إلغاء الفاتورة قبل السداد، مع ضرورة إدخال سبب الإلغاء.</td>\n",
       "      <td>التخصصات الاجتماعية | العمالة المنزلية | كبار السن</td>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>مركز الرياض للسياسات السلوكية</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                            question  \\\n",
       "0  هل تستخدم البوابة والانظمة التابعة لها الحلول الوطنية eSignature؟   \n",
       "1                             ماذا أفعل إذا تم إرجاع الطلب للمراجعة؟   \n",
       "2                                         ماذا يحدث بعد إرسال الطلب؟   \n",
       "3                                      كيف أقدم طلب تعديل فئة مهنية؟   \n",
       "4                                                ما متطلبات التقديم؟   \n",
       "5                     من يمكنه التقديم على خدمة تعديل الفئة المهنية؟   \n",
       "6   هل يمكن للمتقدم أن يحصل على أكثر من تصنيف وبالتالي أكثر من رخصة؟   \n",
       "7        إذا رفض طلب التسجيل والتصنيف هل يحق لي استرداد رسوم الخدمة؟   \n",
       "8                                        ماذا يحدث في حال رفض الطلب؟   \n",
       "9                                            هل يمكن إلغاء الفاتورة؟   \n",
       "\n",
       "                                                                                                                                                            answer  \\\n",
       "0  تقدم الوزارة خدمة التوقيع الالكتروني في اطار ادارة وتوثيق عقود العمل عبر منصة \"قوى\" يمكن للمنشآت انشاء وتوثيق وانهاء عقود العمل للموظفين بشكل الكرتوني بالكامل.   \n",
       "1                                                                                    الدخول إلى “مهامي” ← اختيار مهمة طلب مراجعة ← تعديل البيانات ← إعادة الإرسال.   \n",
       "2                                                                                              يتم تحويل الطلب إلى اللجنة للمراجعة ويتم إشعار المتقدم بحالة الطلب.   \n",
       "3                                                                 من خلال تسجيل الدخول ← الخدمات ← اختيار “طلب تعديل الفئة المهنية” ← تعبئة النموذج ← إرسال الطلب.   \n",
       "4                                                                                                                             أن يكون المتقدم حاصل على ترخيص سابق.   \n",
       "5                                                                                                   الممارس الحاصل على ترخيص من خلال خدمة التسجيل والتصنيف المهني.   \n",
       "6                                                                      نعم، يمكن للمتقدم الحصول على أكثر من رخصة إذا كان يحمل مؤهلات أو دورات أو خبرات تؤهله لذلك.   \n",
       "7                                                                                                    نعم، يحق لك استرداد رسوم خدمة التسجيل والتصنيف إذا رفض الطلب.   \n",
       "8                                                                       يمكنك الاطلاع على سبب الرفض من خلال تفاصيل الطلب، ثم التقديم بطلب جديد بعد معالجة الأسباب.   \n",
       "9                                                                                                 نعم، يمكن إلغاء الفاتورة قبل السداد، مع ضرورة إدخال سبب الإلغاء.   \n",
       "\n",
       "                                        beneficiaries                   sector                        subsite  \n",
       "0    أصحاب عمل | أفراد | العمالة المنزلية | كبار السن               قطاع العمل  مركز الرياض للسياسات السلوكية  \n",
       "1  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "2  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "3  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "4  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "5  التخصصات الاجتماعية | العمالة المنزلية | كبار السن                           مركز الرياض للسياسات السلوكية  \n",
       "6  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "7  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  \n",
       "8  التخصصات الاجتماعية | العمالة المنزلية | كبار السن                           مركز الرياض للسياسات السلوكية  \n",
       "9  التخصصات الاجتماعية | العمالة المنزلية | كبار السن  قطاع التنمية الاجتماعية  مركز الرياض للسياسات السلوكية  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 05 - Clean Classified FAQ\n",
    "# =========================================================\n",
    "\n",
    "df_faq = df_faq_raw.copy()\n",
    "\n",
    "required_faq_cols = [\n",
    "    \"question\", \"answer\", \"beneficiaries\", \"sector\", \"subsite\", \"page_url\"\n",
    "]\n",
    "\n",
    "for col in required_faq_cols:\n",
    "    df_faq = safe_col(df_faq, col, \"\")\n",
    "\n",
    "for col in required_faq_cols:\n",
    "    df_faq[col] = df_faq[col].apply(clean_basic_text)\n",
    "\n",
    "# حذف الصفوف الفارغة أو غير المفيدة\n",
    "before_filter = len(df_faq)\n",
    "df_faq = df_faq[\n",
    "    (df_faq[\"question\"].str.len() > 5) &\n",
    "    (df_faq[\"answer\"].str.len() > 10)\n",
    "].copy()\n",
    "\n",
    "# Metadata\n",
    "df_faq[\"source_type\"] = \"faq\"\n",
    "df_faq[\"source_name\"] = \"HRSD FAQ\"\n",
    "\n",
    "df_faq[\"legal_category\"] = df_faq.apply(\n",
    "    lambda r: clean_basic_text(\n",
    "        f\"{r['beneficiaries']} | {r['sector']} | {r['subsite']}\"\n",
    "    ).strip(\" |\"), axis=1\n",
    ")\n",
    "\n",
    "df_faq[\"document_unit_id\"] = df_faq.apply(\n",
    "    lambda r: make_hash(r[\"source_type\"], r[\"question\"], r[\"answer\"]), axis=1\n",
    ")\n",
    "\n",
    "df_faq[\"text_for_indexing\"] = df_faq.apply(\n",
    "    lambda r: clean_basic_text(\n",
    "        f\"المصدر: {r['source_name']}\\n\"\n",
    "        f\"التصنيف: {r['legal_category']}\\n\"\n",
    "        f\"السؤال: {r['question']}\\n\"\n",
    "        f\"الإجابة: {r['answer']}\"\n",
    "    ), axis=1\n",
    ")\n",
    "\n",
    "df_faq[\"normalized_text\"] = df_faq[\"text_for_indexing\"].apply(normalize_arabic_for_search)\n",
    "\n",
    "before_dedup = len(df_faq)\n",
    "df_faq = df_faq.drop_duplicates(subset=[\"document_unit_id\"]).reset_index(drop=True)\n",
    "\n",
    "df_faq.to_csv(CLEAN_DIR / \"clean_hrsd_faq_classified.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "df_faq.to_excel(CLEAN_DIR / \"clean_hrsd_faq_classified.xlsx\", index=False)\n",
    "\n",
    "print(\"FAQ raw rows:\", before_filter)\n",
    "print(\"FAQ after empty filter:\", before_dedup)\n",
    "print(\"FAQ after dedup:\", len(df_faq))\n",
    "\n",
    "display(df_faq[[\n",
    "    \"question\", \"answer\", \"beneficiaries\", \"sector\", \"subsite\"\n",
    "]].head(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4a4e3c2",
   "metadata": {},
   "source": [
    "## Stage 06 — FAQ Indexing/Evaluation Split\n",
    "\n",
    "This stage splits the cleaned FAQ dataset into two non-overlapping subsets:\n",
    "\n",
    "1. `hrsd_faq_indexing_set.csv` — FAQ records allowed inside the experimental RAG knowledge base.\n",
    "2. `hrsd_faq_evaluation_set.csv` — FAQ records held out exclusively for retrieval evaluation.\n",
    "\n",
    "The split is deterministic and based on a hash of the document identifier. This makes the experiment reproducible across notebook runs while preventing the same FAQ question from appearing in both indexing and evaluation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "565cb6f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "FAQ total: 703\n",
      "FAQ indexing set: 503\n",
      "FAQ evaluation set: 200\n",
      "\n",
      "Evaluation ratio actual: 0.284\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 06 - FAQ Indexing/Evaluation Split to Avoid Leakage\n",
    "# =========================================================\n",
    "\n",
    "df_faq[\"is_eval_record\"] = df_faq[\"document_unit_id\"].apply(\n",
    "    lambda x: deterministic_split_by_hash(x, eval_ratio=FAQ_EVAL_RATIO)\n",
    ")\n",
    "\n",
    "df_faq_indexing = df_faq[~df_faq[\"is_eval_record\"]].copy().reset_index(drop=True)\n",
    "df_faq_evaluation = df_faq[df_faq[\"is_eval_record\"]].copy().reset_index(drop=True)\n",
    "\n",
    "# إذا كانت الداتا صغيرة جداً وضبط التقسيم أعطى صفر، نعمل fallback بسيط\n",
    "if len(df_faq_evaluation) == 0 and len(df_faq) > 5:\n",
    "    df_faq_evaluation = df_faq.sample(frac=FAQ_EVAL_RATIO, random_state=RANDOM_SEED).copy()\n",
    "    df_faq_indexing = df_faq.drop(df_faq_evaluation.index).copy()\n",
    "    df_faq_indexing = df_faq_indexing.reset_index(drop=True)\n",
    "    df_faq_evaluation = df_faq_evaluation.reset_index(drop=True)\n",
    "\n",
    "# حفظ الملفات الأربعة المهمة\n",
    "df_faq_indexing.to_csv(FINAL_DIR / \"hrsd_faq_indexing_set.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "df_faq_evaluation.to_csv(FINAL_DIR / \"hrsd_faq_evaluation_set.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "\n",
    "df_faq_indexing.to_excel(FINAL_DIR / \"hrsd_faq_indexing_set.xlsx\", index=False)\n",
    "df_faq_evaluation.to_excel(FINAL_DIR / \"hrsd_faq_evaluation_set.xlsx\", index=False)\n",
    "\n",
    "print(\"FAQ total:\", len(df_faq))\n",
    "print(\"FAQ indexing set:\", len(df_faq_indexing))\n",
    "print(\"FAQ evaluation set:\", len(df_faq_evaluation))\n",
    "\n",
    "print(\"\\nEvaluation ratio actual:\", round(len(df_faq_evaluation) / max(len(df_faq), 1), 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c3b7947-c5e2-429d-9f1f-6f2a77f94199",
   "metadata": {},
   "source": [
    "<div dir=\"rtl\" style=\"text-align: right; line-height: 2; font-size: 16px;\">\n",
    "\n",
    "<h3>تفسير نتيجة تقسيم الأسئلة الشائعة لمنع التسريب</h3>\n",
    "\n",
    "<p>\n",
    "تهدف هذه المرحلة إلى فصل بيانات الأسئلة الشائعة إلى مجموعتين منفصلتين تماماً:\n",
    "مجموعة للفهرسة داخل قاعدة المعرفة، ومجموعة محجوزة للتقييم.\n",
    "ويتم هذا الفصل لمنع تسريب بيانات التقييم إلى قاعدة الاسترجاع، وهو شرط أساسي لسلامة التقييم العلمي.\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "بلغ إجمالي سجلات الأسئلة الشائعة بعد التنظيف <b>703 سجلاً</b>.\n",
    "خُصّص منها <b>503 سجلاً</b> للفهرسة داخل قاعدة المعرفة التجريبية،\n",
    "بينما حُجز <b>200 سجل</b> للتقييم ولم يدخل قاعدة الفهرسة إطلاقاً.\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "بلغت نسبة الحجز الفعلية <b>0.284</b>، وهي قريبة من النسبة المستهدفة البالغة <b>0.30</b>.\n",
    "ويعود هذا الفرق الطفيف إلى اعتماد آلية تقسيم حتمية قائمة على الدالة الاختزالية\n",
    "<span dir=\"ltr\" style=\"display:inline-block;\">Hash</span>،\n",
    "بدلاً من التقسيم العشوائي.\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "وتُعدّ هذه الآلية نقطة قوة منهجية، لأنها تضمن أن يُوزَّع كل سجل إلى المجموعة نفسها في كل مرة يُعاد فيها التشغيل.\n",
    "وبذلك يصبح التقسيم قابلاً لإعادة الإنتاج بالكامل، وهو معيار مهم في الأبحاث العلمية،\n",
    "حتى وإن لم تُطابق النسبة الرقم المستهدف بدقة.\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "ويعني هذا الفصل أن نتائج تقييم الاسترجاع للأسئلة الشائعة تعكس قدرة النظام الحقيقية على إيجاد إجابات لم يسبق أن فُهرست،\n",
    "وليست نتيجة متضخمة ناتجة عن وجود أسئلة التقييم نفسها داخل قاعدة المعرفة.\n",
    "</p>\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d163ac8-9a41-4b7b-ae82-133576ee99be",
   "metadata": {},
   "source": [
    "### Interpretation — FAQ Split and Leakage Prevention\n",
    "\n",
    "The cleaned FAQ dataset is divided into separate indexing and evaluation subsets. This prevents the retrieval system from being evaluated on questions that were directly included in the knowledge base.\n",
    "\n",
    "This design is important because using the same FAQ records for both indexing and evaluation would artificially inflate retrieval scores and may produce misleading results. By holding out a separate FAQ evaluation set, the notebook provides a more realistic test of the system's ability to retrieve relevant information for unseen questions.\n",
    "\n",
    "**Arabic Explanation**\n",
    "\n",
    "تم تقسيم بيانات الأسئلة الشائعة بعد تنظيفها إلى مجموعتين منفصلتين: مجموعة مخصصة للفهرسة داخل قاعدة المعرفة، ومجموعة أخرى مخصصة للتقييم فقط. الهدف من هذا التقسيم هو منع النظام من اختبار نفسه على نفس الأسئلة التي تم إدخالها مسبقًا داخل قاعدة المعرفة.\n",
    "\n",
    "تعد هذه الخطوة مهمة جدًا في أنظمة RAG؛ لأن استخدام نفس أسئلة FAQ في الفهرسة والتقييم قد يؤدي إلى نتائج مرتفعة بشكل غير حقيقي. في هذه الحالة قد يبدو أن نظام الاسترجاع يعمل بدقة عالية، بينما هو في الواقع يسترجع أسئلة شاهدها مسبقًا أثناء بناء قاعدة المعرفة.\n",
    "\n",
    "لذلك، يساعد فصل مجموعة التقييم عن مجموعة الفهرسة في قياس قدرة النظام بشكل أكثر عدالة وواقعية على استرجاع المعلومات المناسبة عند التعامل مع أسئلة جديدة لم تكن موجودة داخل قاعدة المعرفة التجريبية. كما يساهم هذا الإجراء في تقليل خطر تسريب البيانات ويجعل نتائج التقييم أكثر موثوقية من الناحية الأكاديمية.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3effcf96",
   "metadata": {},
   "source": [
    "## Stage 07 — Data Quality Report\n",
    "\n",
    "This stage generates a data quality report before constructing the RAG knowledge base.\n",
    "\n",
    "The report checks whether the cleaned datasets are complete, whether critical fields are populated, whether duplicated identifiers exist, and whether leakage risks are present. These checks provide an academic quality-assurance layer before the data is used for retrieval experiments.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c753cac7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>check</th>\n",
       "      <th>value</th>\n",
       "      <th>status</th>\n",
       "      <th>interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Legal article records</td>\n",
       "      <td>249</td>\n",
       "      <td>OK</td>\n",
       "      <td>All legal records are retained in the audit dataset after conservative cleaning.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Unique numeric legal articles</td>\n",
       "      <td>245</td>\n",
       "      <td>OK</td>\n",
       "      <td>Coverage of the numeric legal sequence; legal repeated labels such as 'مكرر' are handled separately.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>FAQ records</td>\n",
       "      <td>703</td>\n",
       "      <td>OK</td>\n",
       "      <td>Clean FAQ records after removing empty and duplicate rows.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>FAQ indexing records</td>\n",
       "      <td>503</td>\n",
       "      <td>OK</td>\n",
       "      <td>FAQ records used inside the experimental knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>FAQ evaluation records</td>\n",
       "      <td>200</td>\n",
       "      <td>OK</td>\n",
       "      <td>Held-out FAQ records not indexed in the experimental knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Empty article_text</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>No legal article should have an empty text field.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Empty FAQ answers</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>No FAQ record should have an empty answer.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Duplicated legal article labels</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>True duplicate legal labels must be removed; legal 'مكرر' remains as a different label.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Duplicated legal document IDs</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>Document ID duplicates indicate repeated legal records.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Duplicated FAQ document IDs</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>FAQ duplicates indicate repeated question-answer pairs.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>FAQ leakage between indexing and evaluation</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>Must be zero to avoid inflated retrieval scores.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Active legal articles retained</td>\n",
       "      <td>211</td>\n",
       "      <td>OK</td>\n",
       "      <td>Active legal articles are retained and allowed for RAG indexing.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>Repealed legal articles retained</td>\n",
       "      <td>38</td>\n",
       "      <td>OK</td>\n",
       "      <td>Repealed articles are retained in the audit dataset for transparency and legal completeness.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>Active legal articles used for RAG</td>\n",
       "      <td>211</td>\n",
       "      <td>OK</td>\n",
       "      <td>Only active legal articles should be used in the RAG knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Repealed legal articles archived only</td>\n",
       "      <td>38</td>\n",
       "      <td>OK</td>\n",
       "      <td>Repealed legal articles are retained for audit only and should not be indexed for retrieval.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>Repealed legal articles indexed in RAG</td>\n",
       "      <td>0</td>\n",
       "      <td>OK</td>\n",
       "      <td>Verified using df_articles_active as the legal source allowed for RAG indexing. Repealed legal articles must be zero inside the RAG indexing source.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                          check  value status  \\\n",
       "0                         Legal article records    249     OK   \n",
       "1                 Unique numeric legal articles    245     OK   \n",
       "2                                   FAQ records    703     OK   \n",
       "3                          FAQ indexing records    503     OK   \n",
       "4                        FAQ evaluation records    200     OK   \n",
       "5                            Empty article_text      0     OK   \n",
       "6                             Empty FAQ answers      0     OK   \n",
       "7               Duplicated legal article labels      0     OK   \n",
       "8                 Duplicated legal document IDs      0     OK   \n",
       "9                   Duplicated FAQ document IDs      0     OK   \n",
       "10  FAQ leakage between indexing and evaluation      0     OK   \n",
       "11               Active legal articles retained    211     OK   \n",
       "12             Repealed legal articles retained     38     OK   \n",
       "13           Active legal articles used for RAG    211     OK   \n",
       "14        Repealed legal articles archived only     38     OK   \n",
       "15       Repealed legal articles indexed in RAG      0     OK   \n",
       "\n",
       "                                                                                                                                          interpretation  \n",
       "0                                                                       All legal records are retained in the audit dataset after conservative cleaning.  \n",
       "1                                                   Coverage of the numeric legal sequence; legal repeated labels such as 'مكرر' are handled separately.  \n",
       "2                                                                                             Clean FAQ records after removing empty and duplicate rows.  \n",
       "3                                                                                               FAQ records used inside the experimental knowledge base.  \n",
       "4                                                                                   Held-out FAQ records not indexed in the experimental knowledge base.  \n",
       "5                                                                                                      No legal article should have an empty text field.  \n",
       "6                                                                                                             No FAQ record should have an empty answer.  \n",
       "7                                                                True duplicate legal labels must be removed; legal 'مكرر' remains as a different label.  \n",
       "8                                                                                                Document ID duplicates indicate repeated legal records.  \n",
       "9                                                                                                FAQ duplicates indicate repeated question-answer pairs.  \n",
       "10                                                                                                      Must be zero to avoid inflated retrieval scores.  \n",
       "11                                                                                      Active legal articles are retained and allowed for RAG indexing.  \n",
       "12                                                          Repealed articles are retained in the audit dataset for transparency and legal completeness.  \n",
       "13                                                                                  Only active legal articles should be used in the RAG knowledge base.  \n",
       "14                                                          Repealed legal articles are retained for audit only and should not be indexed for retrieval.  \n",
       "15  Verified using df_articles_active as the legal source allowed for RAG indexing. Repealed legal articles must be zero inside the RAG indexing source.  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data quality report saved successfully.\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\data_quality_report.csv\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\data_quality_report.xlsx\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 07 - Data Quality Report\n",
    "# تقرير جودة البيانات وفحص سلامة قاعدة المعرفة\n",
    "# =========================================================\n",
    "\n",
    "quality_rows = []\n",
    "\n",
    "def add_quality_check(name, value, status, interpretation=\"\"):\n",
    "    quality_rows.append({\n",
    "        \"check\": name,\n",
    "        \"value\": value,\n",
    "        \"status\": status,\n",
    "        \"interpretation\": interpretation,\n",
    "    })\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Basic dataset size checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "add_quality_check(\n",
    "    \"Legal article records\",\n",
    "    len(df_articles),\n",
    "    \"OK\" if len(df_articles) > 0 else \"FAIL\",\n",
    "    \"All legal records are retained in the audit dataset after conservative cleaning.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Unique numeric legal articles\",\n",
    "    df_articles[\"article_number_int\"].dropna().astype(int).nunique(),\n",
    "    \"OK\",\n",
    "    \"Coverage of the numeric legal sequence; legal repeated labels such as 'مكرر' are handled separately.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"FAQ records\",\n",
    "    len(df_faq),\n",
    "    \"OK\" if len(df_faq) > 0 else \"FAIL\",\n",
    "    \"Clean FAQ records after removing empty and duplicate rows.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"FAQ indexing records\",\n",
    "    len(df_faq_indexing),\n",
    "    \"OK\" if len(df_faq_indexing) > 0 else \"WARN\",\n",
    "    \"FAQ records used inside the experimental knowledge base.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"FAQ evaluation records\",\n",
    "    len(df_faq_evaluation),\n",
    "    \"OK\" if len(df_faq_evaluation) > 0 else \"WARN\",\n",
    "    \"Held-out FAQ records not indexed in the experimental knowledge base.\"\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Empty and duplicate checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "empty_article_text = int((df_articles[\"article_text\"].astype(str).str.strip() == \"\").sum())\n",
    "empty_faq_answer = int((df_faq[\"answer\"].astype(str).str.strip() == \"\").sum())\n",
    "\n",
    "dup_article_labels = int(df_articles[\"article_number_label\"].duplicated().sum())\n",
    "dup_articles_doc_id = int(df_articles[\"document_unit_id\"].duplicated().sum())\n",
    "dup_faq = int(df_faq[\"document_unit_id\"].duplicated().sum())\n",
    "\n",
    "add_quality_check(\n",
    "    \"Empty article_text\",\n",
    "    empty_article_text,\n",
    "    \"OK\" if empty_article_text == 0 else \"WARN\",\n",
    "    \"No legal article should have an empty text field.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Empty FAQ answers\",\n",
    "    empty_faq_answer,\n",
    "    \"OK\" if empty_faq_answer == 0 else \"WARN\",\n",
    "    \"No FAQ record should have an empty answer.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Duplicated legal article labels\",\n",
    "    dup_article_labels,\n",
    "    \"OK\" if dup_article_labels == 0 else \"FAIL\",\n",
    "    \"True duplicate legal labels must be removed; legal 'مكرر' remains as a different label.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Duplicated legal document IDs\",\n",
    "    dup_articles_doc_id,\n",
    "    \"OK\" if dup_articles_doc_id == 0 else \"FAIL\",\n",
    "    \"Document ID duplicates indicate repeated legal records.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Duplicated FAQ document IDs\",\n",
    "    dup_faq,\n",
    "    \"OK\" if dup_faq == 0 else \"FAIL\",\n",
    "    \"FAQ duplicates indicate repeated question-answer pairs.\"\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) FAQ leakage check\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "leak_count = len(\n",
    "    set(df_faq_indexing[\"document_unit_id\"]) &\n",
    "    set(df_faq_evaluation[\"document_unit_id\"])\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"FAQ leakage between indexing and evaluation\",\n",
    "    leak_count,\n",
    "    \"OK\" if leak_count == 0 else \"FAIL\",\n",
    "    \"Must be zero to avoid inflated retrieval scores.\"\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Repealed articles audit and RAG safety checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "repealed_count = int((df_articles[\"article_status\"] == \"repealed\").sum())\n",
    "active_count = int((df_articles[\"article_status\"] == \"active\").sum())\n",
    "\n",
    "add_quality_check(\n",
    "    \"Active legal articles retained\",\n",
    "    active_count,\n",
    "    \"OK\" if active_count > 0 else \"FAIL\",\n",
    "    \"Active legal articles are retained and allowed for RAG indexing.\"\n",
    ")\n",
    "\n",
    "add_quality_check(\n",
    "    \"Repealed legal articles retained\",\n",
    "    repealed_count,\n",
    "    \"OK\" if repealed_count > 0 else \"WARN\",\n",
    "    \"Repealed articles are retained in the audit dataset for transparency and legal completeness.\"\n",
    ")\n",
    "\n",
    "# عدد المواد الفعالة المستخدمة كمصدر قانوني مسموح للفهرسة\n",
    "if \"df_articles_active\" in globals() and isinstance(df_articles_active, pd.DataFrame):\n",
    "    active_rag_count = len(df_articles_active)\n",
    "else:\n",
    "    active_rag_count = active_count\n",
    "\n",
    "add_quality_check(\n",
    "    \"Active legal articles used for RAG\",\n",
    "    active_rag_count,\n",
    "    \"OK\" if active_rag_count > 0 else \"FAIL\",\n",
    "    \"Only active legal articles should be used in the RAG knowledge base.\"\n",
    ")\n",
    "\n",
    "# عدد المواد الملغاة المحفوظة كأرشيف\n",
    "if \"df_articles_repealed\" in globals() and isinstance(df_articles_repealed, pd.DataFrame):\n",
    "    repealed_archive_count = len(df_articles_repealed)\n",
    "else:\n",
    "    repealed_archive_count = repealed_count\n",
    "\n",
    "add_quality_check(\n",
    "    \"Repealed legal articles archived only\",\n",
    "    repealed_archive_count,\n",
    "    \"OK\" if repealed_archive_count == repealed_count else \"WARN\",\n",
    "    \"Repealed legal articles are retained for audit only and should not be indexed for retrieval.\"\n",
    ")\n",
    "\n",
    "# أهم فحص: التأكد أن المواد الملغاة لم تدخل مصدر RAG\n",
    "if (\n",
    "    \"kb_experimental\" in globals()\n",
    "    and isinstance(kb_experimental, pd.DataFrame)\n",
    "    and {\"source_type\", \"article_status\"}.issubset(kb_experimental.columns)\n",
    "):\n",
    "    repealed_indexed_count = int(\n",
    "        kb_experimental[\n",
    "            (kb_experimental[\"source_type\"] == \"legal_article\") &\n",
    "            (kb_experimental[\"article_status\"] == \"repealed\")\n",
    "        ].shape[0]\n",
    "    )\n",
    "\n",
    "    check_source = \"Verified using kb_experimental.\"\n",
    "\n",
    "elif (\n",
    "    \"df_articles_active\" in globals()\n",
    "    and isinstance(df_articles_active, pd.DataFrame)\n",
    "    and \"article_status\" in df_articles_active.columns\n",
    "):\n",
    "    repealed_indexed_count = int(\n",
    "        (df_articles_active[\"article_status\"] == \"repealed\").sum()\n",
    "    )\n",
    "\n",
    "    check_source = \"Verified using df_articles_active as the legal source allowed for RAG indexing.\"\n",
    "\n",
    "else:\n",
    "    repealed_indexed_count = None\n",
    "    check_source = \"Could not verify because neither kb_experimental nor df_articles_active was available.\"\n",
    "\n",
    "add_quality_check(\n",
    "    \"Repealed legal articles indexed in RAG\",\n",
    "    \"Not verified\" if repealed_indexed_count is None else repealed_indexed_count,\n",
    "    \"WARN\" if repealed_indexed_count is None else (\"OK\" if repealed_indexed_count == 0 else \"FAIL\"),\n",
    "    check_source + \" Repealed legal articles must be zero inside the RAG indexing source.\"\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Final report\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "quality_report = pd.DataFrame(quality_rows)\n",
    "\n",
    "display(quality_report)\n",
    "\n",
    "quality_report.to_csv(\n",
    "    REPORTS_DIR / \"data_quality_report.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "quality_report.to_excel(\n",
    "    REPORTS_DIR / \"data_quality_report.xlsx\",\n",
    "    index=False\n",
    ")\n",
    "\n",
    "print(\"Data quality report saved successfully.\")\n",
    "print(REPORTS_DIR / \"data_quality_report.csv\")\n",
    "print(REPORTS_DIR / \"data_quality_report.xlsx\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7f7eedf-bbcf-43c2-a625-34c7885a7625",
   "metadata": {},
   "source": [
    "### Interpretation — Data Quality and RAG Safety Validation\n",
    "\n",
    "The quality report verifies that the cleaned legal dataset is complete and auditable, while the retrieval dataset remains safe for RAG indexing.\n",
    "\n",
    "The main safety requirement is that repealed legal articles must not appear inside the experimental RAG knowledge base. In addition, FAQ evaluation records must remain excluded from the indexing subset. These checks reduce the risk of two major problems: generating answers from invalid legal provisions and obtaining inflated retrieval scores due to data leakage.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad48a7cc",
   "metadata": {},
   "source": [
    "## Stage 08 — Build a Safe Unified RAG Knowledge Base\n",
    "\n",
    "This stage constructs the experimental RAG knowledge base from two approved sources:\n",
    "\n",
    "1. Active Saudi Labor Law articles.\n",
    "2. FAQ records assigned to the indexing subset.\n",
    "\n",
    "Repealed legal articles are excluded from the experimental knowledge base and stored separately as an archive. FAQ evaluation records are also excluded to prevent leakage.\n",
    "\n",
    "Two knowledge-base versions are produced:\n",
    "\n",
    "- An **experimental no-leakage KB** used for retrieval evaluation.\n",
    "- A **full production KB** that can be used after evaluation is completed.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "797c8738",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "## Stage 08 Output Summary — Safe Unified RAG Knowledge Base"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_9f5d2 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_9f5d2 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_9f5d2 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_9f5d2_row0_col0, #T_9f5d2_row0_col1, #T_9f5d2_row0_col2, #T_9f5d2_row0_col3, #T_9f5d2_row0_col4, #T_9f5d2_row0_col5, #T_9f5d2_row0_col6, #T_9f5d2_row0_col7, #T_9f5d2_row0_col8, #T_9f5d2_row1_col0, #T_9f5d2_row1_col1, #T_9f5d2_row1_col2, #T_9f5d2_row1_col3, #T_9f5d2_row1_col4, #T_9f5d2_row1_col5, #T_9f5d2_row1_col6, #T_9f5d2_row1_col7, #T_9f5d2_row1_col8, #T_9f5d2_row2_col0, #T_9f5d2_row2_col1, #T_9f5d2_row2_col2, #T_9f5d2_row2_col3, #T_9f5d2_row2_col4, #T_9f5d2_row2_col5, #T_9f5d2_row2_col6, #T_9f5d2_row2_col7, #T_9f5d2_row2_col8 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_9f5d2\">\n",
       "  <caption>Knowledge Base Datasets Generated in Stage 08</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_9f5d2_level0_col0\" class=\"col_heading level0 col0\" >Dataset</th>\n",
       "      <th id=\"T_9f5d2_level0_col1\" class=\"col_heading level0 col1\" >Purpose</th>\n",
       "      <th id=\"T_9f5d2_level0_col2\" class=\"col_heading level0 col2\" >Records</th>\n",
       "      <th id=\"T_9f5d2_level0_col3\" class=\"col_heading level0 col3\" >Columns</th>\n",
       "      <th id=\"T_9f5d2_level0_col4\" class=\"col_heading level0 col4\" >Legal Articles</th>\n",
       "      <th id=\"T_9f5d2_level0_col5\" class=\"col_heading level0 col5\" >FAQ Records</th>\n",
       "      <th id=\"T_9f5d2_level0_col6\" class=\"col_heading level0 col6\" >Repealed Articles</th>\n",
       "      <th id=\"T_9f5d2_level0_col7\" class=\"col_heading level0 col7\" >RAG Usage</th>\n",
       "      <th id=\"T_9f5d2_level0_col8\" class=\"col_heading level0 col8\" >Output File</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_9f5d2_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_9f5d2_row0_col0\" class=\"data row0 col0\" >Experimental RAG Knowledge Base</td>\n",
       "      <td id=\"T_9f5d2_row0_col1\" class=\"data row0 col1\" >Used for retrieval experiments without evaluation leakage</td>\n",
       "      <td id=\"T_9f5d2_row0_col2\" class=\"data row0 col2\" >714</td>\n",
       "      <td id=\"T_9f5d2_row0_col3\" class=\"data row0 col3\" >23</td>\n",
       "      <td id=\"T_9f5d2_row0_col4\" class=\"data row0 col4\" >211</td>\n",
       "      <td id=\"T_9f5d2_row0_col5\" class=\"data row0 col5\" >503</td>\n",
       "      <td id=\"T_9f5d2_row0_col6\" class=\"data row0 col6\" >0</td>\n",
       "      <td id=\"T_9f5d2_row0_col7\" class=\"data row0 col7\" >Active law + FAQ indexing only</td>\n",
       "      <td id=\"T_9f5d2_row0_col8\" class=\"data row0 col8\" >rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_9f5d2_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_9f5d2_row1_col0\" class=\"data row1 col0\" >Full Production RAG Knowledge Base</td>\n",
       "      <td id=\"T_9f5d2_row1_col1\" class=\"data row1 col1\" >Used after evaluation for full production indexing</td>\n",
       "      <td id=\"T_9f5d2_row1_col2\" class=\"data row1 col2\" >914</td>\n",
       "      <td id=\"T_9f5d2_row1_col3\" class=\"data row1 col3\" >23</td>\n",
       "      <td id=\"T_9f5d2_row1_col4\" class=\"data row1 col4\" >211</td>\n",
       "      <td id=\"T_9f5d2_row1_col5\" class=\"data row1 col5\" >703</td>\n",
       "      <td id=\"T_9f5d2_row1_col6\" class=\"data row1 col6\" >0</td>\n",
       "      <td id=\"T_9f5d2_row1_col7\" class=\"data row1 col7\" >Active law + all clean FAQ records</td>\n",
       "      <td id=\"T_9f5d2_row1_col8\" class=\"data row1 col8\" >rag_knowledge_base_dataset_full_production_active_law_only.csv</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_9f5d2_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_9f5d2_row2_col0\" class=\"data row2 col0\" >Repealed Articles Archive</td>\n",
       "      <td id=\"T_9f5d2_row2_col1\" class=\"data row2 col1\" >Audit archive only and excluded from retrieval</td>\n",
       "      <td id=\"T_9f5d2_row2_col2\" class=\"data row2 col2\" >38</td>\n",
       "      <td id=\"T_9f5d2_row2_col3\" class=\"data row2 col3\" >23</td>\n",
       "      <td id=\"T_9f5d2_row2_col4\" class=\"data row2 col4\" >38</td>\n",
       "      <td id=\"T_9f5d2_row2_col5\" class=\"data row2 col5\" >0</td>\n",
       "      <td id=\"T_9f5d2_row2_col6\" class=\"data row2 col6\" >38</td>\n",
       "      <td id=\"T_9f5d2_row2_col7\" class=\"data row2 col7\" >Archive only - not indexed</td>\n",
       "      <td id=\"T_9f5d2_row2_col8\" class=\"data row2 col8\" >legal_articles_repealed_archive_not_indexed.csv</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22a3b8c0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Safety and Leakage Validation"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_f009b caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_f009b th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_f009b td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_f009b_row0_col0, #T_f009b_row0_col1, #T_f009b_row0_col2, #T_f009b_row0_col4, #T_f009b_row1_col0, #T_f009b_row1_col1, #T_f009b_row1_col2, #T_f009b_row1_col4, #T_f009b_row2_col0, #T_f009b_row2_col1, #T_f009b_row2_col2, #T_f009b_row2_col4 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "#T_f009b_row0_col3, #T_f009b_row1_col3, #T_f009b_row2_col3 {\n",
       "  background-color: #DCFCE7;\n",
       "  color: #166534;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_f009b\">\n",
       "  <caption>RAG Safety Checks</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_f009b_level0_col0\" class=\"col_heading level0 col0\" >Safety Check</th>\n",
       "      <th id=\"T_f009b_level0_col1\" class=\"col_heading level0 col1\" >Value</th>\n",
       "      <th id=\"T_f009b_level0_col2\" class=\"col_heading level0 col2\" >Expected</th>\n",
       "      <th id=\"T_f009b_level0_col3\" class=\"col_heading level0 col3\" >Status</th>\n",
       "      <th id=\"T_f009b_level0_col4\" class=\"col_heading level0 col4\" >Interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_f009b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_f009b_row0_col0\" class=\"data row0 col0\" >Repealed articles inside experimental KB</td>\n",
       "      <td id=\"T_f009b_row0_col1\" class=\"data row0 col1\" >0</td>\n",
       "      <td id=\"T_f009b_row0_col2\" class=\"data row0 col2\" >0</td>\n",
       "      <td id=\"T_f009b_row0_col3\" class=\"data row0 col3\" >PASS</td>\n",
       "      <td id=\"T_f009b_row0_col4\" class=\"data row0 col4\" >The experimental KB does not index repealed legal provisions.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f009b_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_f009b_row1_col0\" class=\"data row1 col0\" >Repealed articles inside production KB</td>\n",
       "      <td id=\"T_f009b_row1_col1\" class=\"data row1 col1\" >0</td>\n",
       "      <td id=\"T_f009b_row1_col2\" class=\"data row1 col2\" >0</td>\n",
       "      <td id=\"T_f009b_row1_col3\" class=\"data row1 col3\" >PASS</td>\n",
       "      <td id=\"T_f009b_row1_col4\" class=\"data row1 col4\" >The production KB includes only active legal articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f009b_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_f009b_row2_col0\" class=\"data row2 col0\" >FAQ evaluation leakage inside experimental KB</td>\n",
       "      <td id=\"T_f009b_row2_col1\" class=\"data row2 col1\" >0</td>\n",
       "      <td id=\"T_f009b_row2_col2\" class=\"data row2 col2\" >0</td>\n",
       "      <td id=\"T_f009b_row2_col3\" class=\"data row2 col3\" >PASS</td>\n",
       "      <td id=\"T_f009b_row2_col4\" class=\"data row2 col4\" >Held-out FAQ evaluation records are not included in the experimental KB.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa20cbdf90>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Experimental Knowledge Base Composition"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_3d9b6 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_3d9b6 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_3d9b6 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_3d9b6_row0_col0, #T_3d9b6_row0_col1, #T_3d9b6_row0_col2, #T_3d9b6_row1_col0, #T_3d9b6_row1_col1, #T_3d9b6_row1_col2 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_3d9b6\">\n",
       "  <caption>Experimental KB Records by Source Type</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_3d9b6_level0_col0\" class=\"col_heading level0 col0\" >Source Type</th>\n",
       "      <th id=\"T_3d9b6_level0_col1\" class=\"col_heading level0 col1\" >Records</th>\n",
       "      <th id=\"T_3d9b6_level0_col2\" class=\"col_heading level0 col2\" >Percentage</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_3d9b6_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_3d9b6_row0_col0\" class=\"data row0 col0\" >faq</td>\n",
       "      <td id=\"T_3d9b6_row0_col1\" class=\"data row0 col1\" >503</td>\n",
       "      <td id=\"T_3d9b6_row0_col2\" class=\"data row0 col2\" >70.45%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_3d9b6_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_3d9b6_row1_col0\" class=\"data row1 col0\" >legal_article</td>\n",
       "      <td id=\"T_3d9b6_row1_col1\" class=\"data row1 col1\" >211</td>\n",
       "      <td id=\"T_3d9b6_row1_col2\" class=\"data row1 col2\" >29.55%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad47d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Saved Output Files"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_4353e caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_4353e th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_4353e td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_4353e_row0_col0, #T_4353e_row0_col1, #T_4353e_row0_col2, #T_4353e_row1_col0, #T_4353e_row1_col1, #T_4353e_row1_col2, #T_4353e_row2_col0, #T_4353e_row2_col1, #T_4353e_row2_col2, #T_4353e_row3_col0, #T_4353e_row3_col1, #T_4353e_row3_col2, #T_4353e_row4_col0, #T_4353e_row4_col1, #T_4353e_row4_col2, #T_4353e_row5_col0, #T_4353e_row5_col1, #T_4353e_row5_col2, #T_4353e_row6_col0, #T_4353e_row6_col1, #T_4353e_row6_col2, #T_4353e_row7_col0, #T_4353e_row7_col1, #T_4353e_row7_col2 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_4353e\">\n",
       "  <caption>Stage 08 Saved Output Files</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_4353e_level0_col0\" class=\"col_heading level0 col0\" >File Type</th>\n",
       "      <th id=\"T_4353e_level0_col1\" class=\"col_heading level0 col1\" >Path</th>\n",
       "      <th id=\"T_4353e_level0_col2\" class=\"col_heading level0 col2\" >Purpose</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_4353e_row0_col0\" class=\"data row0 col0\" >Experimental KB - CSV</td>\n",
       "      <td id=\"T_4353e_row0_col1\" class=\"data row0 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv</td>\n",
       "      <td id=\"T_4353e_row0_col2\" class=\"data row0 col2\" >Main dataset for retrieval experiments without FAQ leakage</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_4353e_row1_col0\" class=\"data row1 col0\" >Experimental KB - Excel</td>\n",
       "      <td id=\"T_4353e_row1_col1\" class=\"data row1 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.xlsx</td>\n",
       "      <td id=\"T_4353e_row1_col2\" class=\"data row1 col2\" >Readable Excel version of the experimental RAG knowledge base</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_4353e_row2_col0\" class=\"data row2 col0\" >Production KB - CSV</td>\n",
       "      <td id=\"T_4353e_row2_col1\" class=\"data row2 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production_active_law_only.csv</td>\n",
       "      <td id=\"T_4353e_row2_col2\" class=\"data row2 col2\" >Full production knowledge base after evaluation</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_4353e_row3_col0\" class=\"data row3 col0\" >Production KB - Excel</td>\n",
       "      <td id=\"T_4353e_row3_col1\" class=\"data row3 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production_active_law_only.xlsx</td>\n",
       "      <td id=\"T_4353e_row3_col2\" class=\"data row3 col2\" >Readable Excel version of the full production knowledge base</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
       "      <td id=\"T_4353e_row4_col0\" class=\"data row4 col0\" >Repealed Archive - CSV</td>\n",
       "      <td id=\"T_4353e_row4_col1\" class=\"data row4 col1\" >saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.csv</td>\n",
       "      <td id=\"T_4353e_row4_col2\" class=\"data row4 col2\" >Audit archive for repealed legal articles, not indexed</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
       "      <td id=\"T_4353e_row5_col0\" class=\"data row5 col0\" >Repealed Archive - Excel</td>\n",
       "      <td id=\"T_4353e_row5_col1\" class=\"data row5 col1\" >saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.xlsx</td>\n",
       "      <td id=\"T_4353e_row5_col2\" class=\"data row5 col2\" >Readable Excel version of repealed legal articles archive</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
       "      <td id=\"T_4353e_row6_col0\" class=\"data row6 col0\" >Legacy Experimental KB - CSV</td>\n",
       "      <td id=\"T_4353e_row6_col1\" class=\"data row6 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage.csv</td>\n",
       "      <td id=\"T_4353e_row6_col2\" class=\"data row6 col2\" >Compatibility file for later RAG stages</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4353e_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
       "      <td id=\"T_4353e_row7_col0\" class=\"data row7 col0\" >Legacy Production KB - CSV</td>\n",
       "      <td id=\"T_4353e_row7_col1\" class=\"data row7 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production.csv</td>\n",
       "      <td id=\"T_4353e_row7_col2\" class=\"data row7 col2\" >Compatibility file for later RAG stages</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad47d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Preview — Experimental RAG Knowledge Base"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_ad5e1 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_ad5e1 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_ad5e1 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_ad5e1_row0_col0, #T_ad5e1_row0_col1, #T_ad5e1_row0_col2, #T_ad5e1_row0_col3, #T_ad5e1_row0_col4, #T_ad5e1_row0_col5, #T_ad5e1_row0_col6, #T_ad5e1_row0_col7, #T_ad5e1_row1_col0, #T_ad5e1_row1_col1, #T_ad5e1_row1_col2, #T_ad5e1_row1_col3, #T_ad5e1_row1_col4, #T_ad5e1_row1_col5, #T_ad5e1_row1_col6, #T_ad5e1_row1_col7, #T_ad5e1_row2_col0, #T_ad5e1_row2_col1, #T_ad5e1_row2_col2, #T_ad5e1_row2_col3, #T_ad5e1_row2_col4, #T_ad5e1_row2_col5, #T_ad5e1_row2_col6, #T_ad5e1_row2_col7, #T_ad5e1_row3_col0, #T_ad5e1_row3_col1, #T_ad5e1_row3_col2, #T_ad5e1_row3_col3, #T_ad5e1_row3_col4, #T_ad5e1_row3_col5, #T_ad5e1_row3_col6, #T_ad5e1_row3_col7, #T_ad5e1_row4_col0, #T_ad5e1_row4_col1, #T_ad5e1_row4_col2, #T_ad5e1_row4_col3, #T_ad5e1_row4_col4, #T_ad5e1_row4_col5, #T_ad5e1_row4_col6, #T_ad5e1_row4_col7, #T_ad5e1_row5_col0, #T_ad5e1_row5_col1, #T_ad5e1_row5_col2, #T_ad5e1_row5_col3, #T_ad5e1_row5_col4, #T_ad5e1_row5_col5, #T_ad5e1_row5_col6, #T_ad5e1_row5_col7, #T_ad5e1_row6_col0, #T_ad5e1_row6_col1, #T_ad5e1_row6_col2, #T_ad5e1_row6_col3, #T_ad5e1_row6_col4, #T_ad5e1_row6_col5, #T_ad5e1_row6_col6, #T_ad5e1_row6_col7, #T_ad5e1_row7_col0, #T_ad5e1_row7_col1, #T_ad5e1_row7_col2, #T_ad5e1_row7_col3, #T_ad5e1_row7_col4, #T_ad5e1_row7_col5, #T_ad5e1_row7_col6, #T_ad5e1_row7_col7, #T_ad5e1_row8_col0, #T_ad5e1_row8_col1, #T_ad5e1_row8_col2, #T_ad5e1_row8_col3, #T_ad5e1_row8_col4, #T_ad5e1_row8_col5, #T_ad5e1_row8_col6, #T_ad5e1_row8_col7, #T_ad5e1_row9_col0, #T_ad5e1_row9_col1, #T_ad5e1_row9_col2, #T_ad5e1_row9_col3, #T_ad5e1_row9_col4, #T_ad5e1_row9_col5, #T_ad5e1_row9_col6, #T_ad5e1_row9_col7 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_ad5e1\">\n",
       "  <caption>First 10 Records from the Experimental KB</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_ad5e1_level0_col0\" class=\"col_heading level0 col0\" >record_id</th>\n",
       "      <th id=\"T_ad5e1_level0_col1\" class=\"col_heading level0 col1\" >source_type</th>\n",
       "      <th id=\"T_ad5e1_level0_col2\" class=\"col_heading level0 col2\" >rag_usage</th>\n",
       "      <th id=\"T_ad5e1_level0_col3\" class=\"col_heading level0 col3\" >article_number</th>\n",
       "      <th id=\"T_ad5e1_level0_col4\" class=\"col_heading level0 col4\" >article_status</th>\n",
       "      <th id=\"T_ad5e1_level0_col5\" class=\"col_heading level0 col5\" >question</th>\n",
       "      <th id=\"T_ad5e1_level0_col6\" class=\"col_heading level0 col6\" >source_name</th>\n",
       "      <th id=\"T_ad5e1_level0_col7\" class=\"col_heading level0 col7\" >document_unit_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_ad5e1_row0_col0\" class=\"data row0 col0\" >1</td>\n",
       "      <td id=\"T_ad5e1_row0_col1\" class=\"data row0 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row0_col2\" class=\"data row0 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row0_col3\" class=\"data row0 col3\" >الأولى</td>\n",
       "      <td id=\"T_ad5e1_row0_col4\" class=\"data row0 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row0_col5\" class=\"data row0 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row0_col6\" class=\"data row0 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row0_col7\" class=\"data row0 col7\" >d28fed1c707fb8a6b354171cec6a310c1164782775f0d91e9d13d8b8198af462</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_ad5e1_row1_col0\" class=\"data row1 col0\" >2</td>\n",
       "      <td id=\"T_ad5e1_row1_col1\" class=\"data row1 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row1_col2\" class=\"data row1 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row1_col3\" class=\"data row1 col3\" >الثانية</td>\n",
       "      <td id=\"T_ad5e1_row1_col4\" class=\"data row1 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row1_col5\" class=\"data row1 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row1_col6\" class=\"data row1 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row1_col7\" class=\"data row1 col7\" >4f2961046b5fffdc637e2b7de4dfb1fd862ccc7b9f3069349681b04ff17df638</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_ad5e1_row2_col0\" class=\"data row2 col0\" >3</td>\n",
       "      <td id=\"T_ad5e1_row2_col1\" class=\"data row2 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row2_col2\" class=\"data row2 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row2_col3\" class=\"data row2 col3\" >الثالثة</td>\n",
       "      <td id=\"T_ad5e1_row2_col4\" class=\"data row2 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row2_col5\" class=\"data row2 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row2_col6\" class=\"data row2 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row2_col7\" class=\"data row2 col7\" >82f3c9791caa01e20aff6f25a0e169fbd07f8aa138625fe674d6df6824a31fda</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_ad5e1_row3_col0\" class=\"data row3 col0\" >4</td>\n",
       "      <td id=\"T_ad5e1_row3_col1\" class=\"data row3 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row3_col2\" class=\"data row3 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row3_col3\" class=\"data row3 col3\" >الرابعة</td>\n",
       "      <td id=\"T_ad5e1_row3_col4\" class=\"data row3 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row3_col5\" class=\"data row3 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row3_col6\" class=\"data row3 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row3_col7\" class=\"data row3 col7\" >3457807712bce4c43b55e497232052e55933f7fde19df543c46153e86ca95090</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
       "      <td id=\"T_ad5e1_row4_col0\" class=\"data row4 col0\" >5</td>\n",
       "      <td id=\"T_ad5e1_row4_col1\" class=\"data row4 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row4_col2\" class=\"data row4 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row4_col3\" class=\"data row4 col3\" >الخامسة</td>\n",
       "      <td id=\"T_ad5e1_row4_col4\" class=\"data row4 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row4_col5\" class=\"data row4 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row4_col6\" class=\"data row4 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row4_col7\" class=\"data row4 col7\" >a03900ffe9b536bc7774b84e1eb41826aacf458ed3920b36e463e08ac8bde4cd</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
       "      <td id=\"T_ad5e1_row5_col0\" class=\"data row5 col0\" >6</td>\n",
       "      <td id=\"T_ad5e1_row5_col1\" class=\"data row5 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row5_col2\" class=\"data row5 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row5_col3\" class=\"data row5 col3\" >السادسة</td>\n",
       "      <td id=\"T_ad5e1_row5_col4\" class=\"data row5 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row5_col5\" class=\"data row5 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row5_col6\" class=\"data row5 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row5_col7\" class=\"data row5 col7\" >1157999dfa071a7320606edb9b747429aa71cb7707dcaf5be88784d6c4e2f7ca</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
       "      <td id=\"T_ad5e1_row6_col0\" class=\"data row6 col0\" >7</td>\n",
       "      <td id=\"T_ad5e1_row6_col1\" class=\"data row6 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row6_col2\" class=\"data row6 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row6_col3\" class=\"data row6 col3\" >السابعة</td>\n",
       "      <td id=\"T_ad5e1_row6_col4\" class=\"data row6 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row6_col5\" class=\"data row6 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row6_col6\" class=\"data row6 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row6_col7\" class=\"data row6 col7\" >c91b6c3872f87c320cac960229321ad90710d58e53361f20475d343cc1d88d2d</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
       "      <td id=\"T_ad5e1_row7_col0\" class=\"data row7 col0\" >8</td>\n",
       "      <td id=\"T_ad5e1_row7_col1\" class=\"data row7 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row7_col2\" class=\"data row7 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row7_col3\" class=\"data row7 col3\" >الثامنة</td>\n",
       "      <td id=\"T_ad5e1_row7_col4\" class=\"data row7 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row7_col5\" class=\"data row7 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row7_col6\" class=\"data row7 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row7_col7\" class=\"data row7 col7\" >01eaca9a4fb7e0f5416045832b295fd64085a920f19266ff5bbc0236deddf41d</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
       "      <td id=\"T_ad5e1_row8_col0\" class=\"data row8 col0\" >9</td>\n",
       "      <td id=\"T_ad5e1_row8_col1\" class=\"data row8 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row8_col2\" class=\"data row8 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row8_col3\" class=\"data row8 col3\" >التاسعة</td>\n",
       "      <td id=\"T_ad5e1_row8_col4\" class=\"data row8 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row8_col5\" class=\"data row8 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row8_col6\" class=\"data row8 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row8_col7\" class=\"data row8 col7\" >a0d5a1431be7e4fa5a4411f0ff8222e86afaf8a6e35b994667aae08b4cdfe963</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_ad5e1_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
       "      <td id=\"T_ad5e1_row9_col0\" class=\"data row9 col0\" >10</td>\n",
       "      <td id=\"T_ad5e1_row9_col1\" class=\"data row9 col1\" >legal_article</td>\n",
       "      <td id=\"T_ad5e1_row9_col2\" class=\"data row9 col2\" >indexing_allowed_active_law</td>\n",
       "      <td id=\"T_ad5e1_row9_col3\" class=\"data row9 col3\" >العاشرة</td>\n",
       "      <td id=\"T_ad5e1_row9_col4\" class=\"data row9 col4\" >active</td>\n",
       "      <td id=\"T_ad5e1_row9_col5\" class=\"data row9 col5\" ></td>\n",
       "      <td id=\"T_ad5e1_row9_col6\" class=\"data row9 col6\" >نظام العمل السعودي</td>\n",
       "      <td id=\"T_ad5e1_row9_col7\" class=\"data row9 col7\" >518e66de899a12d4203d77f4bdd3cdac022db77736feac05d635149e954e8dca</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad47d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stage 08 completed successfully.\n",
      "Experimental KB records: 714\n",
      "Full production KB records: 914\n",
      "Repealed archive records: 38\n",
      "All safety checks passed.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 08 - Build Safe Unified RAG Knowledge Base Dataset\n",
    "# بناء قاعدة معرفة موحدة وآمنة لنظام RAG\n",
    "# تستخدم المواد القانونية الفعالة فقط، وتستبعد المواد الملغاة من الفهرسة\n",
    "# =========================================================\n",
    "\n",
    "from IPython.display import display, Markdown\n",
    "\n",
    "FINAL_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Build standardized legal article records\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "def build_article_records(df_articles_part, usage_label=\"indexing_allowed_active_law\"):\n",
    "    \"\"\"\n",
    "    Convert cleaned legal article records into a unified RAG-compatible schema.\n",
    "    \n",
    "    This function is used for both:\n",
    "    - active legal articles allowed for RAG indexing\n",
    "    - repealed legal articles archived for audit only\n",
    "    \"\"\"\n",
    "    df = df_articles_part.copy()\n",
    "    \n",
    "    out = pd.DataFrame({\n",
    "        \"source_type\": df[\"source_type\"],\n",
    "        \"source_name\": df[\"source_name\"],\n",
    "        \"legal_category\": df[\"legal_category\"],\n",
    "        \"bab_label\": df[\"bab_label\"],\n",
    "        \"bab_title\": df[\"bab_title\"],\n",
    "        \"fasl\": df[\"fasl\"],\n",
    "        \"article_title\": df[\"article_title\"],\n",
    "        \"article_number\": df[\"article_number\"],\n",
    "        \"article_number_label\": df.get(\"article_number_label\", \"\"),\n",
    "        \"article_number_int\": df.get(\"article_number_int\", \"\"),\n",
    "        \"article_status\": df.get(\"article_status\", \"\"),\n",
    "        \"rag_usage\": usage_label,\n",
    "        \"question\": \"\",\n",
    "        \"answer\": \"\",\n",
    "        \"beneficiaries\": \"\",\n",
    "        \"sector\": \"\",\n",
    "        \"subsite\": \"\",\n",
    "        \"original_text\": df[\"article_text\"],\n",
    "        \"source_url\": df[\"source_url\"],\n",
    "        \"document_unit_id\": df[\"document_unit_id\"],\n",
    "        \"text_for_indexing\": df[\"text_for_indexing\"],\n",
    "        \"normalized_text\": df[\"normalized_text\"],\n",
    "    })\n",
    "    \n",
    "    return out\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Build standardized FAQ records\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "def build_faq_records(df_faq_part, usage_label=\"indexing_allowed_faq\"):\n",
    "    \"\"\"\n",
    "    Convert cleaned FAQ records into the same unified RAG-compatible schema.\n",
    "    \n",
    "    FAQ records do not have article numbers, so legal-article-specific\n",
    "    metadata fields are filled with empty or not_applicable values.\n",
    "    \"\"\"\n",
    "    df = df_faq_part.copy()\n",
    "    \n",
    "    out = pd.DataFrame({\n",
    "        \"source_type\": df[\"source_type\"],\n",
    "        \"source_name\": df[\"source_name\"],\n",
    "        \"legal_category\": df[\"legal_category\"],\n",
    "        \"bab_label\": \"\",\n",
    "        \"bab_title\": \"\",\n",
    "        \"fasl\": \"\",\n",
    "        \"article_title\": \"\",\n",
    "        \"article_number\": \"\",\n",
    "        \"article_number_label\": \"\",\n",
    "        \"article_number_int\": \"\",\n",
    "        \"article_status\": \"not_applicable\",\n",
    "        \"rag_usage\": usage_label,\n",
    "        \"question\": df[\"question\"],\n",
    "        \"answer\": df[\"answer\"],\n",
    "        \"beneficiaries\": df.get(\"beneficiaries\", \"\"),\n",
    "        \"sector\": df.get(\"sector\", \"\"),\n",
    "        \"subsite\": df.get(\"subsite\", \"\"),\n",
    "        \"original_text\": df[\"answer\"],\n",
    "        \"source_url\": df[\"page_url\"],\n",
    "        \"document_unit_id\": df[\"document_unit_id\"],\n",
    "        \"text_for_indexing\": df[\"text_for_indexing\"],\n",
    "        \"normalized_text\": df[\"normalized_text\"],\n",
    "    })\n",
    "    \n",
    "    return out\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Build source records\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "# Active legal articles only are allowed inside RAG indexing\n",
    "article_records_active = build_article_records(\n",
    "    df_articles_active,\n",
    "    usage_label=\"indexing_allowed_active_law\"\n",
    ")\n",
    "\n",
    "# Repealed legal articles are archived only and must not enter RAG indexing\n",
    "article_records_repealed_archive = build_article_records(\n",
    "    df_articles_repealed,\n",
    "    usage_label=\"archive_only_not_indexed\"\n",
    ")\n",
    "\n",
    "# FAQ indexing subset for experimental KB only, without evaluation leakage\n",
    "faq_indexing_records = build_faq_records(\n",
    "    df_faq_indexing,\n",
    "    usage_label=\"indexing_allowed_faq_no_leakage\"\n",
    ")\n",
    "\n",
    "# Full FAQ records for production KB after evaluation is complete\n",
    "faq_all_records = build_faq_records(\n",
    "    df_faq,\n",
    "    usage_label=\"indexing_allowed_faq_full_production\"\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Experimental KB - no leakage\n",
    "# Active law articles + FAQ indexing subset only\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_kb_experiment = pd.concat(\n",
    "    [article_records_active, faq_indexing_records],\n",
    "    ignore_index=True\n",
    ")\n",
    "\n",
    "df_kb_experiment = (\n",
    "    df_kb_experiment\n",
    "    .drop_duplicates(subset=[\"document_unit_id\"])\n",
    "    .reset_index(drop=True)\n",
    ")\n",
    "\n",
    "df_kb_experiment.insert(\n",
    "    0,\n",
    "    \"record_id\",\n",
    "    range(1, len(df_kb_experiment) + 1)\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Full production KB\n",
    "# Active law articles + all clean FAQ records\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_kb_full_production = pd.concat(\n",
    "    [article_records_active, faq_all_records],\n",
    "    ignore_index=True\n",
    ")\n",
    "\n",
    "df_kb_full_production = (\n",
    "    df_kb_full_production\n",
    "    .drop_duplicates(subset=[\"document_unit_id\"])\n",
    "    .reset_index(drop=True)\n",
    ")\n",
    "\n",
    "df_kb_full_production.insert(\n",
    "    0,\n",
    "    \"record_id\",\n",
    "    range(1, len(df_kb_full_production) + 1)\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Repealed archive only\n",
    "# Not used for retrieval\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_repealed_archive_for_audit = (\n",
    "    article_records_repealed_archive\n",
    "    .copy()\n",
    "    .reset_index(drop=True)\n",
    ")\n",
    "\n",
    "df_repealed_archive_for_audit.insert(\n",
    "    0,\n",
    "    \"record_id\",\n",
    "    range(1, len(df_repealed_archive_for_audit) + 1)\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 7) Safety checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "repealed_in_experiment_kb = int(\n",
    "    (\n",
    "        (df_kb_experiment[\"source_type\"] == \"legal_article\") &\n",
    "        (df_kb_experiment[\"article_status\"] == \"repealed\")\n",
    "    ).sum()\n",
    ")\n",
    "\n",
    "repealed_in_production_kb = int(\n",
    "    (\n",
    "        (df_kb_full_production[\"source_type\"] == \"legal_article\") &\n",
    "        (df_kb_full_production[\"article_status\"] == \"repealed\")\n",
    "    ).sum()\n",
    ")\n",
    "\n",
    "faq_leakage_in_experiment = int(\n",
    "    len(\n",
    "        set(\n",
    "            df_kb_experiment[\n",
    "                df_kb_experiment[\"source_type\"] == \"faq\"\n",
    "            ][\"document_unit_id\"]\n",
    "        )\n",
    "        &\n",
    "        set(df_faq_evaluation[\"document_unit_id\"])\n",
    "    )\n",
    ")\n",
    "\n",
    "assert repealed_in_experiment_kb == 0, (\n",
    "    \"Error: Repealed articles found in experimental RAG KB.\"\n",
    ")\n",
    "\n",
    "assert repealed_in_production_kb == 0, (\n",
    "    \"Error: Repealed articles found in production RAG KB.\"\n",
    ")\n",
    "\n",
    "assert faq_leakage_in_experiment == 0, (\n",
    "    \"Error: FAQ evaluation records found inside experimental KB.\"\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 8) Save outputs\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "experiment_path = FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv\"\n",
    "production_path = FINAL_DIR / \"rag_knowledge_base_dataset_full_production_active_law_only.csv\"\n",
    "repealed_archive_path = FINAL_DIR / \"legal_articles_repealed_archive_not_indexed.csv\"\n",
    "\n",
    "experiment_xlsx_path = FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.xlsx\"\n",
    "production_xlsx_path = FINAL_DIR / \"rag_knowledge_base_dataset_full_production_active_law_only.xlsx\"\n",
    "repealed_archive_xlsx_path = FINAL_DIR / \"legal_articles_repealed_archive_not_indexed.xlsx\"\n",
    "\n",
    "# Legacy-compatible file names for later RAG stages\n",
    "legacy_experiment_path = FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage.csv\"\n",
    "legacy_production_path = FINAL_DIR / \"rag_knowledge_base_dataset_full_production.csv\"\n",
    "\n",
    "df_kb_experiment.to_csv(\n",
    "    experiment_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_kb_full_production.to_csv(\n",
    "    production_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_repealed_archive_for_audit.to_csv(\n",
    "    repealed_archive_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_kb_experiment.to_csv(\n",
    "    legacy_experiment_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_kb_full_production.to_csv(\n",
    "    legacy_production_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_kb_experiment.to_excel(\n",
    "    experiment_xlsx_path,\n",
    "    index=False\n",
    ")\n",
    "\n",
    "df_kb_full_production.to_excel(\n",
    "    production_xlsx_path,\n",
    "    index=False\n",
    ")\n",
    "\n",
    "df_repealed_archive_for_audit.to_excel(\n",
    "    repealed_archive_xlsx_path,\n",
    "    index=False\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 9) Compatibility aliases for later cells\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "kb_experimental = df_kb_experiment.copy()\n",
    "kb_full_production = df_kb_full_production.copy()\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 10) Helper functions for professional summaries\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "def count_source(df, source_type):\n",
    "    if not isinstance(df, pd.DataFrame):\n",
    "        return 0\n",
    "    if \"source_type\" not in df.columns:\n",
    "        return 0\n",
    "    return int((df[\"source_type\"] == source_type).sum())\n",
    "\n",
    "\n",
    "def count_repealed(df):\n",
    "    if not isinstance(df, pd.DataFrame):\n",
    "        return 0\n",
    "    if \"source_type\" not in df.columns or \"article_status\" not in df.columns:\n",
    "        return 0\n",
    "    return int(\n",
    "        (\n",
    "            (df[\"source_type\"] == \"legal_article\") &\n",
    "            (df[\"article_status\"] == \"repealed\")\n",
    "        ).sum()\n",
    "    )\n",
    "\n",
    "\n",
    "def safe_percentage(part, total):\n",
    "    if total == 0:\n",
    "        return 0.0\n",
    "    return round((part / total) * 100, 2)\n",
    "\n",
    "\n",
    "def style_academic_table(styler, caption):\n",
    "    return (\n",
    "        styler\n",
    "        .set_caption(caption)\n",
    "        .set_properties(**{\n",
    "            \"text-align\": \"left\",\n",
    "            \"white-space\": \"normal\",\n",
    "            \"font-size\": \"12px\",\n",
    "            \"vertical-align\": \"top\"\n",
    "        })\n",
    "        .set_table_styles([\n",
    "            {\n",
    "                \"selector\": \"caption\",\n",
    "                \"props\": [\n",
    "                    (\"caption-side\", \"top\"),\n",
    "                    (\"font-size\", \"16px\"),\n",
    "                    (\"font-weight\", \"bold\"),\n",
    "                    (\"text-align\", \"left\"),\n",
    "                    (\"color\", \"#1F2937\"),\n",
    "                    (\"padding\", \"8px\")\n",
    "                ]\n",
    "            },\n",
    "            {\n",
    "                \"selector\": \"th\",\n",
    "                \"props\": [\n",
    "                    (\"background-color\", \"#F3F4F6\"),\n",
    "                    (\"color\", \"#111827\"),\n",
    "                    (\"font-weight\", \"bold\"),\n",
    "                    (\"text-align\", \"center\"),\n",
    "                    (\"border\", \"1px solid #D1D5DB\"),\n",
    "                    (\"padding\", \"6px\")\n",
    "                ]\n",
    "            },\n",
    "            {\n",
    "                \"selector\": \"td\",\n",
    "                \"props\": [\n",
    "                    (\"border\", \"1px solid #E5E7EB\"),\n",
    "                    (\"padding\", \"6px\")\n",
    "                ]\n",
    "            }\n",
    "        ])\n",
    "    )\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 11) Professional Academic Output Summary\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Stage 08 Output Summary — Safe Unified RAG Knowledge Base\"))\n",
    "\n",
    "kb_summary_rows = [\n",
    "    {\n",
    "        \"Dataset\": \"Experimental RAG Knowledge Base\",\n",
    "        \"Purpose\": \"Used for retrieval experiments without evaluation leakage\",\n",
    "        \"Records\": len(df_kb_experiment),\n",
    "        \"Columns\": df_kb_experiment.shape[1],\n",
    "        \"Legal Articles\": count_source(df_kb_experiment, \"legal_article\"),\n",
    "        \"FAQ Records\": count_source(df_kb_experiment, \"faq\"),\n",
    "        \"Repealed Articles\": count_repealed(df_kb_experiment),\n",
    "        \"RAG Usage\": \"Active law + FAQ indexing only\",\n",
    "        \"Output File\": experiment_path.name\n",
    "    },\n",
    "    {\n",
    "        \"Dataset\": \"Full Production RAG Knowledge Base\",\n",
    "        \"Purpose\": \"Used after evaluation for full production indexing\",\n",
    "        \"Records\": len(df_kb_full_production),\n",
    "        \"Columns\": df_kb_full_production.shape[1],\n",
    "        \"Legal Articles\": count_source(df_kb_full_production, \"legal_article\"),\n",
    "        \"FAQ Records\": count_source(df_kb_full_production, \"faq\"),\n",
    "        \"Repealed Articles\": count_repealed(df_kb_full_production),\n",
    "        \"RAG Usage\": \"Active law + all clean FAQ records\",\n",
    "        \"Output File\": production_path.name\n",
    "    },\n",
    "    {\n",
    "        \"Dataset\": \"Repealed Articles Archive\",\n",
    "        \"Purpose\": \"Audit archive only and excluded from retrieval\",\n",
    "        \"Records\": len(df_repealed_archive_for_audit),\n",
    "        \"Columns\": df_repealed_archive_for_audit.shape[1],\n",
    "        \"Legal Articles\": count_source(df_repealed_archive_for_audit, \"legal_article\"),\n",
    "        \"FAQ Records\": count_source(df_repealed_archive_for_audit, \"faq\"),\n",
    "        \"Repealed Articles\": count_repealed(df_repealed_archive_for_audit),\n",
    "        \"RAG Usage\": \"Archive only - not indexed\",\n",
    "        \"Output File\": repealed_archive_path.name\n",
    "    }\n",
    "]\n",
    "\n",
    "kb_summary_df = pd.DataFrame(kb_summary_rows)\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        kb_summary_df\n",
    "        .style\n",
    "        .format({\n",
    "            \"Records\": \"{:,}\",\n",
    "            \"Columns\": \"{:,}\",\n",
    "            \"Legal Articles\": \"{:,}\",\n",
    "            \"FAQ Records\": \"{:,}\",\n",
    "            \"Repealed Articles\": \"{:,}\"\n",
    "        }),\n",
    "        \"Knowledge Base Datasets Generated in Stage 08\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 12) Safety and leakage validation summary\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Safety and Leakage Validation\"))\n",
    "\n",
    "safety_rows = [\n",
    "    {\n",
    "        \"Safety Check\": \"Repealed articles inside experimental KB\",\n",
    "        \"Value\": repealed_in_experiment_kb,\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": \"PASS\" if repealed_in_experiment_kb == 0 else \"FAIL\",\n",
    "        \"Interpretation\": \"The experimental KB does not index repealed legal provisions.\"\n",
    "    },\n",
    "    {\n",
    "        \"Safety Check\": \"Repealed articles inside production KB\",\n",
    "        \"Value\": repealed_in_production_kb,\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": \"PASS\" if repealed_in_production_kb == 0 else \"FAIL\",\n",
    "        \"Interpretation\": \"The production KB includes only active legal articles.\"\n",
    "    },\n",
    "    {\n",
    "        \"Safety Check\": \"FAQ evaluation leakage inside experimental KB\",\n",
    "        \"Value\": faq_leakage_in_experiment,\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": \"PASS\" if faq_leakage_in_experiment == 0 else \"FAIL\",\n",
    "        \"Interpretation\": \"Held-out FAQ evaluation records are not included in the experimental KB.\"\n",
    "    }\n",
    "]\n",
    "\n",
    "safety_df = pd.DataFrame(safety_rows)\n",
    "\n",
    "def highlight_status(value):\n",
    "    if value == \"PASS\":\n",
    "        return \"background-color: #DCFCE7; color: #166534; font-weight: bold;\"\n",
    "    if value == \"FAIL\":\n",
    "        return \"background-color: #FEE2E2; color: #991B1B; font-weight: bold;\"\n",
    "    return \"\"\n",
    "\n",
    "safety_styler = (\n",
    "    safety_df\n",
    "    .style\n",
    "    .format({\n",
    "        \"Value\": \"{:,}\",\n",
    "        \"Expected\": \"{:,}\"\n",
    "    })\n",
    "    .map(highlight_status, subset=[\"Status\"])\n",
    ")\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        safety_styler,\n",
    "        \"RAG Safety Checks\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 13) Experimental KB source composition\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Experimental Knowledge Base Composition\"))\n",
    "\n",
    "source_composition_df = (\n",
    "    df_kb_experiment[\"source_type\"]\n",
    "    .value_counts()\n",
    "    .rename_axis(\"Source Type\")\n",
    "    .reset_index(name=\"Records\")\n",
    ")\n",
    "\n",
    "total_experimental_records = int(source_composition_df[\"Records\"].sum())\n",
    "\n",
    "source_composition_df[\"Percentage\"] = source_composition_df[\"Records\"].apply(\n",
    "    lambda x: safe_percentage(x, total_experimental_records)\n",
    ")\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        source_composition_df\n",
    "        .style\n",
    "        .format({\n",
    "            \"Records\": \"{:,}\",\n",
    "            \"Percentage\": \"{:.2f}%\"\n",
    "        }),\n",
    "        \"Experimental KB Records by Source Type\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 14) Saved files manifest\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Saved Output Files\"))\n",
    "\n",
    "saved_files_df = pd.DataFrame([\n",
    "    {\n",
    "        \"File Type\": \"Experimental KB - CSV\",\n",
    "        \"Path\": str(experiment_path),\n",
    "        \"Purpose\": \"Main dataset for retrieval experiments without FAQ leakage\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Experimental KB - Excel\",\n",
    "        \"Path\": str(experiment_xlsx_path),\n",
    "        \"Purpose\": \"Readable Excel version of the experimental RAG knowledge base\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Production KB - CSV\",\n",
    "        \"Path\": str(production_path),\n",
    "        \"Purpose\": \"Full production knowledge base after evaluation\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Production KB - Excel\",\n",
    "        \"Path\": str(production_xlsx_path),\n",
    "        \"Purpose\": \"Readable Excel version of the full production knowledge base\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Repealed Archive - CSV\",\n",
    "        \"Path\": str(repealed_archive_path),\n",
    "        \"Purpose\": \"Audit archive for repealed legal articles, not indexed\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Repealed Archive - Excel\",\n",
    "        \"Path\": str(repealed_archive_xlsx_path),\n",
    "        \"Purpose\": \"Readable Excel version of repealed legal articles archive\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Legacy Experimental KB - CSV\",\n",
    "        \"Path\": str(legacy_experiment_path),\n",
    "        \"Purpose\": \"Compatibility file for later RAG stages\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Legacy Production KB - CSV\",\n",
    "        \"Path\": str(legacy_production_path),\n",
    "        \"Purpose\": \"Compatibility file for later RAG stages\"\n",
    "    }\n",
    "])\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        saved_files_df.style,\n",
    "        \"Stage 08 Saved Output Files\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 15) Preview of experimental KB\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Preview — Experimental RAG Knowledge Base\"))\n",
    "\n",
    "preview_cols = [\n",
    "    \"record_id\",\n",
    "    \"source_type\",\n",
    "    \"rag_usage\",\n",
    "    \"article_number\",\n",
    "    \"article_status\",\n",
    "    \"question\",\n",
    "    \"source_name\",\n",
    "    \"document_unit_id\"\n",
    "]\n",
    "\n",
    "preview_cols = [\n",
    "    col for col in preview_cols\n",
    "    if col in df_kb_experiment.columns\n",
    "]\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        df_kb_experiment[preview_cols]\n",
    "        .head(10)\n",
    "        .style,\n",
    "        \"First 10 Records from the Experimental KB\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 16) Final completion message\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "print(\"Stage 08 completed successfully.\")\n",
    "print(f\"Experimental KB records: {len(df_kb_experiment):,}\")\n",
    "print(f\"Full production KB records: {len(df_kb_full_production):,}\")\n",
    "print(f\"Repealed archive records: {len(df_repealed_archive_for_audit):,}\")\n",
    "print(\"All safety checks passed.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25761262-6993-455a-a7db-fdcf29c80525",
   "metadata": {},
   "source": [
    "### Interpretation — Safe Unified RAG Knowledge Base\n",
    "\n",
    "The unified knowledge base is designed to balance legal coverage, retrieval safety, and evaluation validity.\n",
    "\n",
    "The experimental version includes only active legal articles and FAQ indexing records. This ensures that the RAG system retrieves from valid legal sources and does not see the held-out FAQ evaluation questions. The production version includes all cleaned FAQ records and can be used after the evaluation phase.\n",
    "\n",
    "This separation supports fair experimentation and reduces the likelihood of hallucination caused by retrieving invalid or leaked content.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d4e2e787-425a-499b-a514-b13b711cdf59",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Legal records inside experimental KB: 211\n",
      "Repealed articles inside experimental KB: 0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>article_status</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>active</th>\n",
       "      <td>211</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                count\n",
       "article_status       \n",
       "active            211"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>source_type</th>\n",
       "      <th>article_number_label</th>\n",
       "      <th>article_number_int</th>\n",
       "      <th>article_status</th>\n",
       "      <th>rag_usage</th>\n",
       "      <th>article_title</th>\n",
       "      <th>source_name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الأولى:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الثانية :</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الثالثة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الرابعة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الخامسة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة السادسة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>7</td>\n",
       "      <td>7</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة السابعة :</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>8</td>\n",
       "      <td>8</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة الثامنة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>9</td>\n",
       "      <td>9</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة التاسعة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>legal_article</td>\n",
       "      <td>10</td>\n",
       "      <td>10</td>\n",
       "      <td>active</td>\n",
       "      <td>indexing_allowed_active_law</td>\n",
       "      <td>المادة العاشرة:</td>\n",
       "      <td>نظام العمل السعودي</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     source_type article_number_label article_number_int article_status                    rag_usage     article_title         source_name\n",
       "0  legal_article                    1                  1         active  indexing_allowed_active_law    المادة الأولى:  نظام العمل السعودي\n",
       "1  legal_article                    2                  2         active  indexing_allowed_active_law  المادة الثانية :  نظام العمل السعودي\n",
       "2  legal_article                    3                  3         active  indexing_allowed_active_law   المادة الثالثة:  نظام العمل السعودي\n",
       "3  legal_article                    4                  4         active  indexing_allowed_active_law   المادة الرابعة:  نظام العمل السعودي\n",
       "4  legal_article                    5                  5         active  indexing_allowed_active_law   المادة الخامسة:  نظام العمل السعودي\n",
       "5  legal_article                    6                  6         active  indexing_allowed_active_law   المادة السادسة:  نظام العمل السعودي\n",
       "6  legal_article                    7                  7         active  indexing_allowed_active_law  المادة السابعة :  نظام العمل السعودي\n",
       "7  legal_article                    8                  8         active  indexing_allowed_active_law   المادة الثامنة:  نظام العمل السعودي\n",
       "8  legal_article                    9                  9         active  indexing_allowed_active_law   المادة التاسعة:  نظام العمل السعودي\n",
       "9  legal_article                   10                 10         active  indexing_allowed_active_law   المادة العاشرة:  نظام العمل السعودي"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Quick checkpoint: verify that experimental KB contains active legal articles only\n",
    "legal_kb_preview_cols = [\n",
    "    \"source_type\", \"article_number_label\", \"article_number_int\",\n",
    "    \"article_status\", \"rag_usage\", \"article_title\", \"source_name\"\n",
    "]\n",
    "mask = df_kb_experiment[\"source_type\"] == \"legal_article\"\n",
    "legal_kb_status = df_kb_experiment.loc[mask, \"article_status\"].value_counts().to_frame(\"count\")\n",
    "\n",
    "print(\"Legal records inside experimental KB:\", int(mask.sum()))\n",
    "print(\"Repealed articles inside experimental KB:\", int((df_kb_experiment.loc[mask, \"article_status\"] == \"repealed\").sum()))\n",
    "display(legal_kb_status)\n",
    "display(df_kb_experiment.loc[mask, legal_kb_preview_cols].head(10))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f2e45ab3-d62f-4823-914a-8ef3a1877406",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Checkpoint passed: Experimental KB contains active legal articles only.\n"
     ]
    }
   ],
   "source": [
    "assert int((df_kb_experiment.loc[mask, \"article_status\"] == \"repealed\").sum()) == 0, \\\n",
    "    \"Error: Repealed legal articles found inside experimental KB.\"\n",
    "\n",
    "assert set(df_kb_experiment.loc[mask, \"article_status\"].unique()) == {\"active\"}, \\\n",
    "    \"Error: Experimental legal KB must contain active legal articles only.\"\n",
    "\n",
    "print(\"Checkpoint passed: Experimental KB contains active legal articles only.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db61180f-573a-4097-9aa5-5886035f601b",
   "metadata": {},
   "source": [
    "### Checkpoint — Experimental KB Safety\n",
    "\n",
    "This checkpoint verifies that the experimental legal knowledge base contains active legal articles only.\n",
    "\n",
    "A valid result requires the number of repealed legal articles inside the experimental KB to be zero. Passing this checkpoint means that repealed articles were successfully preserved for auditability but excluded from retrieval indexing.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7229ff72",
   "metadata": {},
   "source": [
    "## Stage 09 — Build the Initial Evaluation Dataset\n",
    "\n",
    "This stage builds the initial evaluation dataset from the held-out FAQ records.\n",
    "\n",
    "At this point, the evaluation set contains FAQ questions only. Manual legal article questions and out-of-scope questions are added in the following enrichment stage. This staged design makes the evaluation dataset easier to inspect, extend, and validate.\n",
    "\n",
    "The final evaluation dataset is intended to test three behaviours:\n",
    "\n",
    "1. Retrieving relevant FAQ records.\n",
    "2. Retrieving the correct legal article for legal questions.\n",
    "3. Rejecting or redirecting questions outside the Saudi Labor Law scope.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e2d851eb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "## Stage 09 Output Summary — Evaluation Dataset Construction"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_4f32b caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_4f32b th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_4f32b td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_4f32b_row0_col0, #T_4f32b_row0_col1, #T_4f32b_row0_col3, #T_4f32b_row1_col0, #T_4f32b_row1_col1, #T_4f32b_row1_col3, #T_4f32b_row2_col0, #T_4f32b_row2_col1, #T_4f32b_row2_col3, #T_4f32b_row3_col0, #T_4f32b_row3_col1, #T_4f32b_row3_col3 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "#T_4f32b_row0_col2, #T_4f32b_row1_col2, #T_4f32b_row2_col2, #T_4f32b_row3_col2 {\n",
       "  background-color: #DCFCE7;\n",
       "  color: #166534;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_4f32b\">\n",
       "  <caption>Evaluation Dataset Summary</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_4f32b_level0_col0\" class=\"col_heading level0 col0\" >Component</th>\n",
       "      <th id=\"T_4f32b_level0_col1\" class=\"col_heading level0 col1\" >Count</th>\n",
       "      <th id=\"T_4f32b_level0_col2\" class=\"col_heading level0 col2\" >Status</th>\n",
       "      <th id=\"T_4f32b_level0_col3\" class=\"col_heading level0 col3\" >Interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_4f32b_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_4f32b_row0_col0\" class=\"data row0 col0\" >Held-out FAQ Evaluation Set</td>\n",
       "      <td id=\"T_4f32b_row0_col1\" class=\"data row0 col1\" >200</td>\n",
       "      <td id=\"T_4f32b_row0_col2\" class=\"data row0 col2\" >PASS</td>\n",
       "      <td id=\"T_4f32b_row0_col3\" class=\"data row0 col3\" >FAQ records reserved for evaluation and excluded from the experimental knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4f32b_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_4f32b_row1_col0\" class=\"data row1 col0\" >Manual Legal Evaluation Questions</td>\n",
       "      <td id=\"T_4f32b_row1_col1\" class=\"data row1 col1\" >0</td>\n",
       "      <td id=\"T_4f32b_row1_col2\" class=\"data row1 col2\" >OK</td>\n",
       "      <td id=\"T_4f32b_row1_col3\" class=\"data row1 col3\" >Not added in this stage. Legal questions are added later in Stage 09.5.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4f32b_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_4f32b_row2_col0\" class=\"data row2 col0\" >Out-of-Scope Evaluation Questions</td>\n",
       "      <td id=\"T_4f32b_row2_col1\" class=\"data row2 col1\" >0</td>\n",
       "      <td id=\"T_4f32b_row2_col2\" class=\"data row2 col2\" >OK</td>\n",
       "      <td id=\"T_4f32b_row2_col3\" class=\"data row2 col3\" >Not added in this stage. Out-of-scope tests are added later in Stage 09.5.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_4f32b_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_4f32b_row3_col0\" class=\"data row3 col0\" >Total Evaluation Questions</td>\n",
       "      <td id=\"T_4f32b_row3_col1\" class=\"data row3 col1\" >200</td>\n",
       "      <td id=\"T_4f32b_row3_col2\" class=\"data row3 col2\" >PASS</td>\n",
       "      <td id=\"T_4f32b_row3_col3\" class=\"data row3 col3\" >Initial evaluation dataset created from held-out FAQ records only.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad5810>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Safety and Leakage Validation"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_6cd88 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_6cd88 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_6cd88 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_6cd88_row0_col0, #T_6cd88_row0_col1, #T_6cd88_row0_col2, #T_6cd88_row0_col4, #T_6cd88_row1_col0, #T_6cd88_row1_col1, #T_6cd88_row1_col2, #T_6cd88_row1_col4, #T_6cd88_row2_col0, #T_6cd88_row2_col1, #T_6cd88_row2_col2, #T_6cd88_row2_col4, #T_6cd88_row3_col0, #T_6cd88_row3_col1, #T_6cd88_row3_col2, #T_6cd88_row3_col4 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "#T_6cd88_row0_col3, #T_6cd88_row1_col3, #T_6cd88_row3_col3 {\n",
       "  background-color: #DCFCE7;\n",
       "  color: #166534;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "#T_6cd88_row2_col3 {\n",
       "  background-color: #FEF3C7;\n",
       "  color: #92400E;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_6cd88\">\n",
       "  <caption>Evaluation Dataset Safety Checks</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_6cd88_level0_col0\" class=\"col_heading level0 col0\" >Safety Check</th>\n",
       "      <th id=\"T_6cd88_level0_col1\" class=\"col_heading level0 col1\" >Value</th>\n",
       "      <th id=\"T_6cd88_level0_col2\" class=\"col_heading level0 col2\" >Expected</th>\n",
       "      <th id=\"T_6cd88_level0_col3\" class=\"col_heading level0 col3\" >Status</th>\n",
       "      <th id=\"T_6cd88_level0_col4\" class=\"col_heading level0 col4\" >Interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_6cd88_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_6cd88_row0_col0\" class=\"data row0 col0\" >FAQ evaluation leakage inside experimental KB</td>\n",
       "      <td id=\"T_6cd88_row0_col1\" class=\"data row0 col1\" >0</td>\n",
       "      <td id=\"T_6cd88_row0_col2\" class=\"data row0 col2\" >0</td>\n",
       "      <td id=\"T_6cd88_row0_col3\" class=\"data row0 col3\" >PASS</td>\n",
       "      <td id=\"T_6cd88_row0_col4\" class=\"data row0 col4\" >Held-out FAQ records must not appear inside the experimental RAG knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6cd88_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_6cd88_row1_col0\" class=\"data row1 col0\" >Missing legal gold document IDs</td>\n",
       "      <td id=\"T_6cd88_row1_col1\" class=\"data row1 col1\" >0</td>\n",
       "      <td id=\"T_6cd88_row1_col2\" class=\"data row1 col2\" >0</td>\n",
       "      <td id=\"T_6cd88_row1_col3\" class=\"data row1 col3\" >PASS</td>\n",
       "      <td id=\"T_6cd88_row1_col4\" class=\"data row1 col4\" >No missing gold legal references are expected. At this stage, legal questions have not been added yet.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6cd88_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_6cd88_row2_col0\" class=\"data row2 col0\" >Duplicate evaluation questions</td>\n",
       "      <td id=\"T_6cd88_row2_col1\" class=\"data row2 col1\" >1</td>\n",
       "      <td id=\"T_6cd88_row2_col2\" class=\"data row2 col2\" >0</td>\n",
       "      <td id=\"T_6cd88_row2_col3\" class=\"data row2 col3\" >WARN</td>\n",
       "      <td id=\"T_6cd88_row2_col4\" class=\"data row2 col4\" >Duplicate questions should be reviewed because they may bias evaluation results.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6cd88_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_6cd88_row3_col0\" class=\"data row3 col0\" >Unknown evaluation types</td>\n",
       "      <td id=\"T_6cd88_row3_col1\" class=\"data row3 col1\" >0</td>\n",
       "      <td id=\"T_6cd88_row3_col2\" class=\"data row3 col2\" >0</td>\n",
       "      <td id=\"T_6cd88_row3_col3\" class=\"data row3 col3\" >PASS</td>\n",
       "      <td id=\"T_6cd88_row3_col4\" class=\"data row3 col4\" >Only faq_retrieval, legal_article_retrieval, and out_of_scope are allowed.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad4690>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Evaluation Dataset Composition"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_93dbe caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_93dbe th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_93dbe td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_93dbe_row0_col0, #T_93dbe_row0_col1, #T_93dbe_row0_col2 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_93dbe\">\n",
       "  <caption>Evaluation Questions by Type</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_93dbe_level0_col0\" class=\"col_heading level0 col0\" >Evaluation Type</th>\n",
       "      <th id=\"T_93dbe_level0_col1\" class=\"col_heading level0 col1\" >Records</th>\n",
       "      <th id=\"T_93dbe_level0_col2\" class=\"col_heading level0 col2\" >Percentage</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_93dbe_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_93dbe_row0_col0\" class=\"data row0 col0\" >faq_retrieval</td>\n",
       "      <td id=\"T_93dbe_row0_col1\" class=\"data row0 col1\" >200</td>\n",
       "      <td id=\"T_93dbe_row0_col2\" class=\"data row0 col2\" >100.00%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad56d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Metadata Coverage — FAQ Evaluation Set"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_a8eb7 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_a8eb7 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_a8eb7 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_a8eb7_row0_col0, #T_a8eb7_row0_col1, #T_a8eb7_row0_col2, #T_a8eb7_row0_col3, #T_a8eb7_row1_col0, #T_a8eb7_row1_col1, #T_a8eb7_row1_col2, #T_a8eb7_row1_col3, #T_a8eb7_row2_col0, #T_a8eb7_row2_col1, #T_a8eb7_row2_col2, #T_a8eb7_row2_col3, #T_a8eb7_row3_col0, #T_a8eb7_row3_col1, #T_a8eb7_row3_col2, #T_a8eb7_row3_col3 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_a8eb7\">\n",
       "  <caption>FAQ Evaluation Metadata Coverage</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_a8eb7_level0_col0\" class=\"col_heading level0 col0\" >Metadata Field</th>\n",
       "      <th id=\"T_a8eb7_level0_col1\" class=\"col_heading level0 col1\" >Non-empty Records</th>\n",
       "      <th id=\"T_a8eb7_level0_col2\" class=\"col_heading level0 col2\" >Unique Values</th>\n",
       "      <th id=\"T_a8eb7_level0_col3\" class=\"col_heading level0 col3\" >Interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_a8eb7_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_a8eb7_row0_col0\" class=\"data row0 col0\" >beneficiaries</td>\n",
       "      <td id=\"T_a8eb7_row0_col1\" class=\"data row0 col1\" >200</td>\n",
       "      <td id=\"T_a8eb7_row0_col2\" class=\"data row0 col2\" >11</td>\n",
       "      <td id=\"T_a8eb7_row0_col3\" class=\"data row0 col3\" >Represents the target beneficiary categories in FAQ evaluation questions.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_a8eb7_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_a8eb7_row1_col0\" class=\"data row1 col0\" >sector</td>\n",
       "      <td id=\"T_a8eb7_row1_col1\" class=\"data row1 col1\" >176</td>\n",
       "      <td id=\"T_a8eb7_row1_col2\" class=\"data row1 col2\" >5</td>\n",
       "      <td id=\"T_a8eb7_row1_col3\" class=\"data row1 col3\" >Represents the sector classification provided by the FAQ source.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_a8eb7_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_a8eb7_row2_col0\" class=\"data row2 col0\" >subsite</td>\n",
       "      <td id=\"T_a8eb7_row2_col1\" class=\"data row2 col1\" >200</td>\n",
       "      <td id=\"T_a8eb7_row2_col2\" class=\"data row2 col2\" >1</td>\n",
       "      <td id=\"T_a8eb7_row2_col3\" class=\"data row2 col3\" >Represents the ministry subsite or service area associated with the FAQ.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_a8eb7_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_a8eb7_row3_col0\" class=\"data row3 col0\" >legal_category</td>\n",
       "      <td id=\"T_a8eb7_row3_col1\" class=\"data row3 col1\" >200</td>\n",
       "      <td id=\"T_a8eb7_row3_col2\" class=\"data row3 col2\" >17</td>\n",
       "      <td id=\"T_a8eb7_row3_col3\" class=\"data row3 col3\" >Represents the legal or service category used for filtering and analysis.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad56d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Saved Output Files"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_f605f caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_f605f th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_f605f td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_f605f_row0_col0, #T_f605f_row0_col1, #T_f605f_row0_col2, #T_f605f_row1_col0, #T_f605f_row1_col1, #T_f605f_row1_col2 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_f605f\">\n",
       "  <caption>Stage 09 Saved Output Files</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_f605f_level0_col0\" class=\"col_heading level0 col0\" >File Type</th>\n",
       "      <th id=\"T_f605f_level0_col1\" class=\"col_heading level0 col1\" >Path</th>\n",
       "      <th id=\"T_f605f_level0_col2\" class=\"col_heading level0 col2\" >Purpose</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_f605f_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_f605f_row0_col0\" class=\"data row0 col0\" >Evaluation Dataset - CSV</td>\n",
       "      <td id=\"T_f605f_row0_col1\" class=\"data row0 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv</td>\n",
       "      <td id=\"T_f605f_row0_col2\" class=\"data row0 col2\" >Main evaluation dataset used in retrieval evaluation stages</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f605f_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_f605f_row1_col0\" class=\"data row1 col0\" >Evaluation Dataset - Excel</td>\n",
       "      <td id=\"T_f605f_row1_col1\" class=\"data row1 col1\" >saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.xlsx</td>\n",
       "      <td id=\"T_f605f_row1_col2\" class=\"data row1 col2\" >Readable Excel version of the evaluation dataset</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad56d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "## Preview — Evaluation Dataset"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_97af9 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "  color: #1F2937;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_97af9 th {\n",
       "  background-color: #F3F4F6;\n",
       "  color: #111827;\n",
       "  font-weight: bold;\n",
       "  text-align: center;\n",
       "  border: 1px solid #D1D5DB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_97af9 td {\n",
       "  border: 1px solid #E5E7EB;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_97af9_row0_col0, #T_97af9_row0_col1, #T_97af9_row0_col2, #T_97af9_row0_col3, #T_97af9_row0_col4, #T_97af9_row0_col5, #T_97af9_row0_col6, #T_97af9_row0_col7, #T_97af9_row1_col0, #T_97af9_row1_col1, #T_97af9_row1_col2, #T_97af9_row1_col3, #T_97af9_row1_col4, #T_97af9_row1_col5, #T_97af9_row1_col6, #T_97af9_row1_col7, #T_97af9_row2_col0, #T_97af9_row2_col1, #T_97af9_row2_col2, #T_97af9_row2_col3, #T_97af9_row2_col4, #T_97af9_row2_col5, #T_97af9_row2_col6, #T_97af9_row2_col7, #T_97af9_row3_col0, #T_97af9_row3_col1, #T_97af9_row3_col2, #T_97af9_row3_col3, #T_97af9_row3_col4, #T_97af9_row3_col5, #T_97af9_row3_col6, #T_97af9_row3_col7, #T_97af9_row4_col0, #T_97af9_row4_col1, #T_97af9_row4_col2, #T_97af9_row4_col3, #T_97af9_row4_col4, #T_97af9_row4_col5, #T_97af9_row4_col6, #T_97af9_row4_col7, #T_97af9_row5_col0, #T_97af9_row5_col1, #T_97af9_row5_col2, #T_97af9_row5_col3, #T_97af9_row5_col4, #T_97af9_row5_col5, #T_97af9_row5_col6, #T_97af9_row5_col7, #T_97af9_row6_col0, #T_97af9_row6_col1, #T_97af9_row6_col2, #T_97af9_row6_col3, #T_97af9_row6_col4, #T_97af9_row6_col5, #T_97af9_row6_col6, #T_97af9_row6_col7, #T_97af9_row7_col0, #T_97af9_row7_col1, #T_97af9_row7_col2, #T_97af9_row7_col3, #T_97af9_row7_col4, #T_97af9_row7_col5, #T_97af9_row7_col6, #T_97af9_row7_col7, #T_97af9_row8_col0, #T_97af9_row8_col1, #T_97af9_row8_col2, #T_97af9_row8_col3, #T_97af9_row8_col4, #T_97af9_row8_col5, #T_97af9_row8_col6, #T_97af9_row8_col7, #T_97af9_row9_col0, #T_97af9_row9_col1, #T_97af9_row9_col2, #T_97af9_row9_col3, #T_97af9_row9_col4, #T_97af9_row9_col5, #T_97af9_row9_col6, #T_97af9_row9_col7 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "  vertical-align: top;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_97af9\">\n",
       "  <caption>First 10 Records from the Evaluation Dataset</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_97af9_level0_col0\" class=\"col_heading level0 col0\" >eval_id</th>\n",
       "      <th id=\"T_97af9_level0_col1\" class=\"col_heading level0 col1\" >eval_type</th>\n",
       "      <th id=\"T_97af9_level0_col2\" class=\"col_heading level0 col2\" >question</th>\n",
       "      <th id=\"T_97af9_level0_col3\" class=\"col_heading level0 col3\" >gold_source_type</th>\n",
       "      <th id=\"T_97af9_level0_col4\" class=\"col_heading level0 col4\" >gold_document_unit_id</th>\n",
       "      <th id=\"T_97af9_level0_col5\" class=\"col_heading level0 col5\" >gold_article_numbers</th>\n",
       "      <th id=\"T_97af9_level0_col6\" class=\"col_heading level0 col6\" >is_out_of_scope</th>\n",
       "      <th id=\"T_97af9_level0_col7\" class=\"col_heading level0 col7\" >notes</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_97af9_row0_col0\" class=\"data row0 col0\" >1</td>\n",
       "      <td id=\"T_97af9_row0_col1\" class=\"data row0 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row0_col2\" class=\"data row0 col2\" >كيف أقدم طلب تعديل فئة مهنية؟</td>\n",
       "      <td id=\"T_97af9_row0_col3\" class=\"data row0 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row0_col4\" class=\"data row0 col4\" >cc6e9febbf279b2ef3f918b5f577a00c1b3aa387c9586eb0c0fd5041c1ea6a5f</td>\n",
       "      <td id=\"T_97af9_row0_col5\" class=\"data row0 col5\" ></td>\n",
       "      <td id=\"T_97af9_row0_col6\" class=\"data row0 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row0_col7\" class=\"data row0 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_97af9_row1_col0\" class=\"data row1 col0\" >2</td>\n",
       "      <td id=\"T_97af9_row1_col1\" class=\"data row1 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row1_col2\" class=\"data row1 col2\" >هل يمكن إلغاء الفاتورة؟</td>\n",
       "      <td id=\"T_97af9_row1_col3\" class=\"data row1 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row1_col4\" class=\"data row1 col4\" >08ba662a93ceb81fb2b5bb34f30c25d8671da5e7b2357c2b63ec341c90e9ad5e</td>\n",
       "      <td id=\"T_97af9_row1_col5\" class=\"data row1 col5\" ></td>\n",
       "      <td id=\"T_97af9_row1_col6\" class=\"data row1 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row1_col7\" class=\"data row1 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_97af9_row2_col0\" class=\"data row2 col0\" >3</td>\n",
       "      <td id=\"T_97af9_row2_col1\" class=\"data row2 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row2_col2\" class=\"data row2 col2\" >ماذا يحدث بعد قبول الطلب؟</td>\n",
       "      <td id=\"T_97af9_row2_col3\" class=\"data row2 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row2_col4\" class=\"data row2 col4\" >769f3118ab9018c0aacc4e962a6fa9d6a3c4661cd1bea8a1394bfa9217563a13</td>\n",
       "      <td id=\"T_97af9_row2_col5\" class=\"data row2 col5\" ></td>\n",
       "      <td id=\"T_97af9_row2_col6\" class=\"data row2 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row2_col7\" class=\"data row2 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_97af9_row3_col0\" class=\"data row3 col0\" >4</td>\n",
       "      <td id=\"T_97af9_row3_col1\" class=\"data row3 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row3_col2\" class=\"data row3 col2\" >من يمكنه التقديم على الخدمة (التسجيل والتصنيف المهني)؟</td>\n",
       "      <td id=\"T_97af9_row3_col3\" class=\"data row3 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row3_col4\" class=\"data row3 col4\" >b76268b4f60317c0abd6ba926305487b071db8464105d0bfb6dcf68169da2acb</td>\n",
       "      <td id=\"T_97af9_row3_col5\" class=\"data row3 col5\" ></td>\n",
       "      <td id=\"T_97af9_row3_col6\" class=\"data row3 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row3_col7\" class=\"data row3 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
       "      <td id=\"T_97af9_row4_col0\" class=\"data row4 col0\" >5</td>\n",
       "      <td id=\"T_97af9_row4_col1\" class=\"data row4 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row4_col2\" class=\"data row4 col2\" >كم تبلغ رسوم الخدمة؟</td>\n",
       "      <td id=\"T_97af9_row4_col3\" class=\"data row4 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row4_col4\" class=\"data row4 col4\" >5f1569e1908e2da4574a316406ea60d3f65d9d439b99af9a09401a8e72135aee</td>\n",
       "      <td id=\"T_97af9_row4_col5\" class=\"data row4 col5\" ></td>\n",
       "      <td id=\"T_97af9_row4_col6\" class=\"data row4 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row4_col7\" class=\"data row4 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
       "      <td id=\"T_97af9_row5_col0\" class=\"data row5 col0\" >6</td>\n",
       "      <td id=\"T_97af9_row5_col1\" class=\"data row5 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row5_col2\" class=\"data row5 col2\" >ما هي المهن الاجتماعية المستهدفة بالخدمة؟</td>\n",
       "      <td id=\"T_97af9_row5_col3\" class=\"data row5 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row5_col4\" class=\"data row5 col4\" >9b78d586b9e8add5808f77feb5181547da19e8d565fc64bdb5b7347a9b7f9e7a</td>\n",
       "      <td id=\"T_97af9_row5_col5\" class=\"data row5 col5\" ></td>\n",
       "      <td id=\"T_97af9_row5_col6\" class=\"data row5 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row5_col7\" class=\"data row5 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
       "      <td id=\"T_97af9_row6_col0\" class=\"data row6 col0\" >7</td>\n",
       "      <td id=\"T_97af9_row6_col1\" class=\"data row6 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row6_col2\" class=\"data row6 col2\" >كيف يتم التحقق من استلام العامل للأجر الذي سيتم التنفيذ عليه في عقد العمل الموثق سندًا تنفيذيًا؟</td>\n",
       "      <td id=\"T_97af9_row6_col3\" class=\"data row6 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row6_col4\" class=\"data row6 col4\" >529eb529660f41db8b40d522f7914d1ea87fc055ca2c0bd6017d77fdd2d80aa3</td>\n",
       "      <td id=\"T_97af9_row6_col5\" class=\"data row6 col5\" ></td>\n",
       "      <td id=\"T_97af9_row6_col6\" class=\"data row6 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row6_col7\" class=\"data row6 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
       "      <td id=\"T_97af9_row7_col0\" class=\"data row7 col0\" >8</td>\n",
       "      <td id=\"T_97af9_row7_col1\" class=\"data row7 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row7_col2\" class=\"data row7 col2\" >ماهو بند العقد الخاضع للتنفيذ لعقد العمل الموثق سندًا تنفيذيًا؟</td>\n",
       "      <td id=\"T_97af9_row7_col3\" class=\"data row7 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row7_col4\" class=\"data row7 col4\" >1f0a32b43d1d888523da1db089e2b5f6310977c6d4065dff65bf39462c298fd2</td>\n",
       "      <td id=\"T_97af9_row7_col5\" class=\"data row7 col5\" ></td>\n",
       "      <td id=\"T_97af9_row7_col6\" class=\"data row7 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row7_col7\" class=\"data row7 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
       "      <td id=\"T_97af9_row8_col0\" class=\"data row8 col0\" >9</td>\n",
       "      <td id=\"T_97af9_row8_col1\" class=\"data row8 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row8_col2\" class=\"data row8 col2\" >كم عدد المواعيد التي يمكنني حجزها؟</td>\n",
       "      <td id=\"T_97af9_row8_col3\" class=\"data row8 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row8_col4\" class=\"data row8 col4\" >ffa3b44c28e7b6d17ad298d8305e7477ba5146a843476e6c69ddb3e284d28da9</td>\n",
       "      <td id=\"T_97af9_row8_col5\" class=\"data row8 col5\" ></td>\n",
       "      <td id=\"T_97af9_row8_col6\" class=\"data row8 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row8_col7\" class=\"data row8 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_97af9_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
       "      <td id=\"T_97af9_row9_col0\" class=\"data row9 col0\" >10</td>\n",
       "      <td id=\"T_97af9_row9_col1\" class=\"data row9 col1\" >faq_retrieval</td>\n",
       "      <td id=\"T_97af9_row9_col2\" class=\"data row9 col2\" >ما هي قنوات الخدمة لبطاقة امتياز لكبار السن؟</td>\n",
       "      <td id=\"T_97af9_row9_col3\" class=\"data row9 col3\" >faq</td>\n",
       "      <td id=\"T_97af9_row9_col4\" class=\"data row9 col4\" >55b8b57061d919d736d4508bc811e1b7380f7b59f8682c28cdba279d86aa221e</td>\n",
       "      <td id=\"T_97af9_row9_col5\" class=\"data row9 col5\" ></td>\n",
       "      <td id=\"T_97af9_row9_col6\" class=\"data row9 col6\" >False</td>\n",
       "      <td id=\"T_97af9_row9_col7\" class=\"data row9 col7\" >Held-out FAQ question. Not indexed in experimental KB.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa22ad56d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stage 09 completed successfully.\n",
      "Evaluation dataset records: 200\n",
      "FAQ evaluation records: 200\n",
      "Legal article evaluation records: 0 - added later in Stage 09.5\n",
      "Out-of-scope evaluation records: 0 - added later in Stage 09.5\n",
      "FAQ leakage into experimental KB: 0\n",
      "Missing legal gold records: 0\n",
      "Duplicate evaluation questions: 1\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 09 - Build Evaluation Dataset (FAQ Held-Out Only)\n",
    "# بناء Dataset تقييم آمن من أسئلة FAQ المحجوزة فقط\n",
    "# الأسئلة القانونية وأسئلة خارج النطاق تُضاف لاحقاً في Stage 09.5\n",
    "# =========================================================\n",
    "\n",
    "from IPython.display import display, Markdown\n",
    "import pandas as pd\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Prepare FAQ held-out evaluation set\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "faq_eval = df_faq_evaluation.copy()\n",
    "\n",
    "df_eval_faq = pd.DataFrame({\n",
    "    \"question\": faq_eval[\"question\"],\n",
    "    \"expected_answer\": faq_eval[\"answer\"],\n",
    "    \"beneficiaries\": faq_eval[\"beneficiaries\"],\n",
    "    \"sector\": faq_eval[\"sector\"],\n",
    "    \"subsite\": faq_eval[\"subsite\"],\n",
    "    \"legal_category\": faq_eval[\"legal_category\"],\n",
    "    \"source_name\": faq_eval[\"source_name\"],\n",
    "    \"source_url\": faq_eval[\"page_url\"],\n",
    "    \"eval_type\": \"faq_retrieval\",\n",
    "    \"gold_source_type\": \"faq\",\n",
    "    \"gold_document_unit_id\": faq_eval[\"document_unit_id\"],\n",
    "    \"gold_document_unit_ids\": faq_eval[\"document_unit_id\"],\n",
    "    \"gold_article_number\": \"\",\n",
    "    \"gold_article_numbers\": \"\",\n",
    "    \"gold_article_title\": \"\",\n",
    "    \"is_out_of_scope\": False,\n",
    "    \"notes\": \"Held-out FAQ question. Not indexed in experimental KB.\",\n",
    "})\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Helper function for legal gold articles\n",
    "# تستخدم لاحقاً في Stage 09.5 عند إضافة الأسئلة القانونية اليدوية\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "def get_legal_gold(article_numbers):\n",
    "    \"\"\"\n",
    "    Returns gold metadata for one or multiple active legal articles.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    article_numbers : list\n",
    "        List of article_number_int values, e.g. [53] or [84, 85].\n",
    "    \n",
    "    Returns\n",
    "    -------\n",
    "    dict\n",
    "        Gold legal metadata used for retrieval evaluation.\n",
    "    \"\"\"\n",
    "    nums = [int(n) for n in article_numbers]\n",
    "\n",
    "    matched = (\n",
    "        df_articles_active[\n",
    "            df_articles_active[\"article_number_int\"].astype(int).isin(nums)\n",
    "        ]\n",
    "        .sort_values(\"article_number_int\")\n",
    "        .copy()\n",
    "    )\n",
    "\n",
    "    if matched.empty:\n",
    "        return {\n",
    "            \"expected_answer\": \"\",\n",
    "            \"gold_document_unit_id\": \"\",\n",
    "            \"gold_document_unit_ids\": \"\",\n",
    "            \"gold_article_number\": \"\",\n",
    "            \"gold_article_numbers\": \",\".join(map(str, nums)),\n",
    "            \"gold_article_title\": \"\",\n",
    "            \"source_url\": \"\",\n",
    "            \"notes_extra\": \"WARNING: gold article was not found in active legal articles.\"\n",
    "        }\n",
    "\n",
    "    return {\n",
    "        \"expected_answer\": \"\\n\\n\".join(matched[\"article_text\"].astype(str).tolist()),\n",
    "        \"gold_document_unit_id\": matched[\"document_unit_id\"].iloc[0],\n",
    "        \"gold_document_unit_ids\": \"|\".join(matched[\"document_unit_id\"].astype(str).tolist()),\n",
    "        \"gold_article_number\": str(matched[\"article_number_int\"].iloc[0]),\n",
    "        \"gold_article_numbers\": \",\".join(\n",
    "            matched[\"article_number_int\"].astype(int).astype(str).tolist()\n",
    "        ),\n",
    "        \"gold_article_title\": \" | \".join(matched[\"article_title\"].astype(str).tolist()),\n",
    "        \"source_url\": matched[\"source_url\"].iloc[0],\n",
    "        \"notes_extra\": \"\"\n",
    "    }\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Manual legal and out-of-scope placeholders\n",
    "# تبقى فارغة في هذه المرحلة لتجنب تعدد مصادر بناء df_eval\n",
    "# سيتم إثراء df_eval في Stage 09.5\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "manual_specs = []\n",
    "out_of_scope_questions = []\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Build manual rows\n",
    "# في هذه المرحلة ستكون فارغة عمداً\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "manual_eval_questions = []\n",
    "\n",
    "for item in manual_specs:\n",
    "    gold = get_legal_gold(item[\"article_numbers\"])\n",
    "    \n",
    "    manual_eval_questions.append({\n",
    "        \"question\": item[\"question\"],\n",
    "        \"expected_answer\": gold[\"expected_answer\"],\n",
    "        \"beneficiaries\": \"\",\n",
    "        \"sector\": item[\"sector\"],\n",
    "        \"subsite\": item[\"subsite\"],\n",
    "        \"legal_category\": item[\"legal_category\"],\n",
    "        \"source_name\": \"Manual Legal Evaluation\",\n",
    "        \"source_url\": gold[\"source_url\"],\n",
    "        \"eval_type\": \"legal_article_retrieval\",\n",
    "        \"gold_source_type\": \"legal_article\",\n",
    "        \"gold_document_unit_id\": gold[\"gold_document_unit_id\"],\n",
    "        \"gold_document_unit_ids\": gold[\"gold_document_unit_ids\"],\n",
    "        \"gold_article_number\": gold[\"gold_article_number\"],\n",
    "        \"gold_article_numbers\": gold[\"gold_article_numbers\"],\n",
    "        \"gold_article_title\": gold[\"gold_article_title\"],\n",
    "        \"is_out_of_scope\": False,\n",
    "        \"notes\": item[\"notes\"] + (\" \" + gold[\"notes_extra\"] if gold[\"notes_extra\"] else \"\"),\n",
    "    })\n",
    "\n",
    "for q in out_of_scope_questions:\n",
    "    manual_eval_questions.append({\n",
    "        \"question\": q,\n",
    "        \"expected_answer\": \"هذا السؤال خارج نطاق نظام العمل السعودي.\",\n",
    "        \"beneficiaries\": \"\",\n",
    "        \"sector\": \"\",\n",
    "        \"subsite\": \"\",\n",
    "        \"legal_category\": \"Out of Scope\",\n",
    "        \"source_name\": \"Manual Evaluation\",\n",
    "        \"source_url\": \"\",\n",
    "        \"eval_type\": \"out_of_scope\",\n",
    "        \"gold_source_type\": \"\",\n",
    "        \"gold_document_unit_id\": \"\",\n",
    "        \"gold_document_unit_ids\": \"\",\n",
    "        \"gold_article_number\": \"\",\n",
    "        \"gold_article_numbers\": \"\",\n",
    "        \"gold_article_title\": \"\",\n",
    "        \"is_out_of_scope\": True,\n",
    "        \"notes\": \"Out-of-scope rejection test.\",\n",
    "    })\n",
    "\n",
    "df_eval_manual = pd.DataFrame(manual_eval_questions)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Build unified evaluation dataset\n",
    "# FAQ only at this stage\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "if len(df_eval_manual) > 0:\n",
    "    df_eval = pd.concat([df_eval_faq, df_eval_manual], ignore_index=True)\n",
    "else:\n",
    "    df_eval = df_eval_faq.copy()\n",
    "\n",
    "df_eval = df_eval.reset_index(drop=True)\n",
    "\n",
    "if \"eval_id\" in df_eval.columns:\n",
    "    df_eval = df_eval.drop(columns=[\"eval_id\"])\n",
    "\n",
    "df_eval.insert(0, \"eval_id\", range(1, len(df_eval) + 1))\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Quality checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "faq_eval_count = int((df_eval[\"eval_type\"] == \"faq_retrieval\").sum())\n",
    "legal_eval_count = int((df_eval[\"eval_type\"] == \"legal_article_retrieval\").sum())\n",
    "oos_eval_count = int((df_eval[\"eval_type\"] == \"out_of_scope\").sum())\n",
    "\n",
    "missing_legal_gold = df_eval[\n",
    "    (df_eval[\"eval_type\"] == \"legal_article_retrieval\") &\n",
    "    (df_eval[\"gold_document_unit_ids\"].astype(str).str.strip() == \"\")\n",
    "]\n",
    "\n",
    "faq_leakage_eval = int(\n",
    "    len(\n",
    "        set(df_eval_faq[\"gold_document_unit_id\"].astype(str))\n",
    "        &\n",
    "        set(\n",
    "            df_kb_experiment[\n",
    "                df_kb_experiment[\"source_type\"] == \"faq\"\n",
    "            ][\"document_unit_id\"].astype(str)\n",
    "        )\n",
    "    )\n",
    ")\n",
    "\n",
    "duplicate_eval_questions = int(\n",
    "    df_eval[\"question\"].fillna(\"\").astype(str).str.strip().duplicated().sum()\n",
    ")\n",
    "\n",
    "allowed_eval_types = {\n",
    "    \"faq_retrieval\",\n",
    "    \"legal_article_retrieval\",\n",
    "    \"out_of_scope\"\n",
    "}\n",
    "\n",
    "unknown_eval_types = sorted(\n",
    "    set(df_eval[\"eval_type\"].dropna().astype(str).unique()) - allowed_eval_types\n",
    ")\n",
    "\n",
    "assert len(missing_legal_gold) == 0, (\n",
    "    \"Error: Some legal evaluation questions have no gold legal document ID.\"\n",
    ")\n",
    "\n",
    "assert faq_leakage_eval == 0, (\n",
    "    \"Error: FAQ evaluation records leaked into experimental KB.\"\n",
    ")\n",
    "\n",
    "assert len(unknown_eval_types) == 0, (\n",
    "    f\"Error: Unknown eval_type values found: {unknown_eval_types}\"\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 7) Save outputs\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "eval_csv_path = FINAL_DIR / \"rag_evaluation_dataset.csv\"\n",
    "eval_xlsx_path = FINAL_DIR / \"rag_evaluation_dataset.xlsx\"\n",
    "\n",
    "df_eval.to_csv(\n",
    "    eval_csv_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_eval.to_excel(\n",
    "    eval_xlsx_path,\n",
    "    index=False\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 8) Styling helpers\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "def status_label(condition):\n",
    "    return \"PASS\" if condition else \"FAIL\"\n",
    "\n",
    "\n",
    "def warning_label(condition):\n",
    "    return \"OK\" if condition else \"WARN\"\n",
    "\n",
    "\n",
    "def highlight_status(value):\n",
    "    if value in [\"PASS\", \"OK\"]:\n",
    "        return \"background-color: #DCFCE7; color: #166534; font-weight: bold;\"\n",
    "    if value == \"WARN\":\n",
    "        return \"background-color: #FEF3C7; color: #92400E; font-weight: bold;\"\n",
    "    if value == \"FAIL\":\n",
    "        return \"background-color: #FEE2E2; color: #991B1B; font-weight: bold;\"\n",
    "    return \"\"\n",
    "\n",
    "\n",
    "def style_academic_table(styler, caption):\n",
    "    return (\n",
    "        styler\n",
    "        .set_caption(caption)\n",
    "        .set_properties(**{\n",
    "            \"text-align\": \"left\",\n",
    "            \"white-space\": \"normal\",\n",
    "            \"font-size\": \"12px\",\n",
    "            \"vertical-align\": \"top\"\n",
    "        })\n",
    "        .set_table_styles([\n",
    "            {\n",
    "                \"selector\": \"caption\",\n",
    "                \"props\": [\n",
    "                    (\"caption-side\", \"top\"),\n",
    "                    (\"font-size\", \"16px\"),\n",
    "                    (\"font-weight\", \"bold\"),\n",
    "                    (\"text-align\", \"left\"),\n",
    "                    (\"color\", \"#1F2937\"),\n",
    "                    (\"padding\", \"8px\")\n",
    "                ]\n",
    "            },\n",
    "            {\n",
    "                \"selector\": \"th\",\n",
    "                \"props\": [\n",
    "                    (\"background-color\", \"#F3F4F6\"),\n",
    "                    (\"color\", \"#111827\"),\n",
    "                    (\"font-weight\", \"bold\"),\n",
    "                    (\"text-align\", \"center\"),\n",
    "                    (\"border\", \"1px solid #D1D5DB\"),\n",
    "                    (\"padding\", \"6px\")\n",
    "                ]\n",
    "            },\n",
    "            {\n",
    "                \"selector\": \"td\",\n",
    "                \"props\": [\n",
    "                    (\"border\", \"1px solid #E5E7EB\"),\n",
    "                    (\"padding\", \"6px\")\n",
    "                ]\n",
    "            }\n",
    "        ])\n",
    "    )\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 9) Professional summary table\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Stage 09 Output Summary — Evaluation Dataset Construction\"))\n",
    "\n",
    "evaluation_summary_df = pd.DataFrame([\n",
    "    {\n",
    "        \"Component\": \"Held-out FAQ Evaluation Set\",\n",
    "        \"Count\": faq_eval_count,\n",
    "        \"Status\": \"PASS\" if faq_eval_count > 0 else \"FAIL\",\n",
    "        \"Interpretation\": \"FAQ records reserved for evaluation and excluded from the experimental knowledge base.\"\n",
    "    },\n",
    "    {\n",
    "        \"Component\": \"Manual Legal Evaluation Questions\",\n",
    "        \"Count\": legal_eval_count,\n",
    "        \"Status\": \"OK\",\n",
    "        \"Interpretation\": \"Not added in this stage. Legal questions are added later in Stage 09.5.\"\n",
    "    },\n",
    "    {\n",
    "        \"Component\": \"Out-of-Scope Evaluation Questions\",\n",
    "        \"Count\": oos_eval_count,\n",
    "        \"Status\": \"OK\",\n",
    "        \"Interpretation\": \"Not added in this stage. Out-of-scope tests are added later in Stage 09.5.\"\n",
    "    },\n",
    "    {\n",
    "        \"Component\": \"Total Evaluation Questions\",\n",
    "        \"Count\": len(df_eval),\n",
    "        \"Status\": \"PASS\" if len(df_eval) > 0 else \"FAIL\",\n",
    "        \"Interpretation\": \"Initial evaluation dataset created from held-out FAQ records only.\"\n",
    "    }\n",
    "])\n",
    "\n",
    "evaluation_summary_styler = (\n",
    "    evaluation_summary_df\n",
    "    .style\n",
    "    .format({\"Count\": \"{:,}\"})\n",
    "    .map(highlight_status, subset=[\"Status\"])\n",
    ")\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        evaluation_summary_styler,\n",
    "        \"Evaluation Dataset Summary\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 10) Evaluation safety checks table\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Safety and Leakage Validation\"))\n",
    "\n",
    "evaluation_safety_df = pd.DataFrame([\n",
    "    {\n",
    "        \"Safety Check\": \"FAQ evaluation leakage inside experimental KB\",\n",
    "        \"Value\": faq_leakage_eval,\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": status_label(faq_leakage_eval == 0),\n",
    "        \"Interpretation\": \"Held-out FAQ records must not appear inside the experimental RAG knowledge base.\"\n",
    "    },\n",
    "    {\n",
    "        \"Safety Check\": \"Missing legal gold document IDs\",\n",
    "        \"Value\": len(missing_legal_gold),\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": status_label(len(missing_legal_gold) == 0),\n",
    "        \"Interpretation\": \"No missing gold legal references are expected. At this stage, legal questions have not been added yet.\"\n",
    "    },\n",
    "    {\n",
    "        \"Safety Check\": \"Duplicate evaluation questions\",\n",
    "        \"Value\": duplicate_eval_questions,\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": warning_label(duplicate_eval_questions == 0),\n",
    "        \"Interpretation\": \"Duplicate questions should be reviewed because they may bias evaluation results.\"\n",
    "    },\n",
    "    {\n",
    "        \"Safety Check\": \"Unknown evaluation types\",\n",
    "        \"Value\": len(unknown_eval_types),\n",
    "        \"Expected\": 0,\n",
    "        \"Status\": status_label(len(unknown_eval_types) == 0),\n",
    "        \"Interpretation\": \"Only faq_retrieval, legal_article_retrieval, and out_of_scope are allowed.\"\n",
    "    }\n",
    "])\n",
    "\n",
    "evaluation_safety_styler = (\n",
    "    evaluation_safety_df\n",
    "    .style\n",
    "    .format({\n",
    "        \"Value\": \"{:,}\",\n",
    "        \"Expected\": \"{:,}\"\n",
    "    })\n",
    "    .map(highlight_status, subset=[\"Status\"])\n",
    ")\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        evaluation_safety_styler,\n",
    "        \"Evaluation Dataset Safety Checks\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 11) Evaluation dataset composition\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Evaluation Dataset Composition\"))\n",
    "\n",
    "eval_type_df = (\n",
    "    df_eval[\"eval_type\"]\n",
    "    .value_counts()\n",
    "    .rename_axis(\"Evaluation Type\")\n",
    "    .reset_index(name=\"Records\")\n",
    ")\n",
    "\n",
    "eval_type_df[\"Percentage\"] = (\n",
    "    eval_type_df[\"Records\"] / eval_type_df[\"Records\"].sum() * 100\n",
    ").round(2)\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        eval_type_df\n",
    "        .style\n",
    "        .format({\n",
    "            \"Records\": \"{:,}\",\n",
    "            \"Percentage\": \"{:.2f}%\"\n",
    "        }),\n",
    "        \"Evaluation Questions by Type\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 12) Metadata coverage table\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Metadata Coverage — FAQ Evaluation Set\"))\n",
    "\n",
    "metadata_coverage_df = pd.DataFrame([\n",
    "    {\n",
    "        \"Metadata Field\": \"beneficiaries\",\n",
    "        \"Non-empty Records\": int(df_eval[\"beneficiaries\"].fillna(\"\").astype(str).str.strip().ne(\"\").sum()),\n",
    "        \"Unique Values\": int(df_eval[\"beneficiaries\"].replace(\"\", pd.NA).dropna().nunique()),\n",
    "        \"Interpretation\": \"Represents the target beneficiary categories in FAQ evaluation questions.\"\n",
    "    },\n",
    "    {\n",
    "        \"Metadata Field\": \"sector\",\n",
    "        \"Non-empty Records\": int(df_eval[\"sector\"].fillna(\"\").astype(str).str.strip().ne(\"\").sum()),\n",
    "        \"Unique Values\": int(df_eval[\"sector\"].replace(\"\", pd.NA).dropna().nunique()),\n",
    "        \"Interpretation\": \"Represents the sector classification provided by the FAQ source.\"\n",
    "    },\n",
    "    {\n",
    "        \"Metadata Field\": \"subsite\",\n",
    "        \"Non-empty Records\": int(df_eval[\"subsite\"].fillna(\"\").astype(str).str.strip().ne(\"\").sum()),\n",
    "        \"Unique Values\": int(df_eval[\"subsite\"].replace(\"\", pd.NA).dropna().nunique()),\n",
    "        \"Interpretation\": \"Represents the ministry subsite or service area associated with the FAQ.\"\n",
    "    },\n",
    "    {\n",
    "        \"Metadata Field\": \"legal_category\",\n",
    "        \"Non-empty Records\": int(df_eval[\"legal_category\"].fillna(\"\").astype(str).str.strip().ne(\"\").sum()),\n",
    "        \"Unique Values\": int(df_eval[\"legal_category\"].replace(\"\", pd.NA).dropna().nunique()),\n",
    "        \"Interpretation\": \"Represents the legal or service category used for filtering and analysis.\"\n",
    "    }\n",
    "])\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        metadata_coverage_df\n",
    "        .style\n",
    "        .format({\n",
    "            \"Non-empty Records\": \"{:,}\",\n",
    "            \"Unique Values\": \"{:,}\"\n",
    "        }),\n",
    "        \"FAQ Evaluation Metadata Coverage\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 13) Saved files manifest\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Saved Output Files\"))\n",
    "\n",
    "saved_eval_files_df = pd.DataFrame([\n",
    "    {\n",
    "        \"File Type\": \"Evaluation Dataset - CSV\",\n",
    "        \"Path\": str(eval_csv_path),\n",
    "        \"Purpose\": \"Main evaluation dataset used in retrieval evaluation stages\"\n",
    "    },\n",
    "    {\n",
    "        \"File Type\": \"Evaluation Dataset - Excel\",\n",
    "        \"Path\": str(eval_xlsx_path),\n",
    "        \"Purpose\": \"Readable Excel version of the evaluation dataset\"\n",
    "    }\n",
    "])\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        saved_eval_files_df.style,\n",
    "        \"Stage 09 Saved Output Files\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 14) Preview table\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(Markdown(\"## Preview — Evaluation Dataset\"))\n",
    "\n",
    "preview_cols = [\n",
    "    \"eval_id\",\n",
    "    \"eval_type\",\n",
    "    \"question\",\n",
    "    \"gold_source_type\",\n",
    "    \"gold_document_unit_id\",\n",
    "    \"gold_article_numbers\",\n",
    "    \"is_out_of_scope\",\n",
    "    \"notes\"\n",
    "]\n",
    "\n",
    "preview_cols = [col for col in preview_cols if col in df_eval.columns]\n",
    "\n",
    "display(\n",
    "    style_academic_table(\n",
    "        df_eval[preview_cols]\n",
    "        .head(10)\n",
    "        .style,\n",
    "        \"First 10 Records from the Evaluation Dataset\"\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 15) Final completion message\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "print(\"Stage 09 completed successfully.\")\n",
    "print(f\"Evaluation dataset records: {len(df_eval):,}\")\n",
    "print(f\"FAQ evaluation records: {faq_eval_count:,}\")\n",
    "print(f\"Legal article evaluation records: {legal_eval_count:,} - added later in Stage 09.5\")\n",
    "print(f\"Out-of-scope evaluation records: {oos_eval_count:,} - added later in Stage 09.5\")\n",
    "print(f\"FAQ leakage into experimental KB: {faq_leakage_eval:,}\")\n",
    "print(f\"Missing legal gold records: {len(missing_legal_gold):,}\")\n",
    "print(f\"Duplicate evaluation questions: {duplicate_eval_questions:,}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cef9ea5a-9aeb-4eea-9778-b5b9da2d9595",
   "metadata": {},
   "source": [
    "### Interpretation — Initial Evaluation Dataset Construction\n",
    "\n",
    "The initial evaluation dataset is created from FAQ records that were intentionally excluded from the experimental knowledge base. This prevents the retrieval system from being tested on records that it has already indexed.\n",
    "\n",
    "Manual legal questions and out-of-scope tests are added in the next stage to strengthen the evaluation. Keeping these additions separate makes the pipeline clearer and helps distinguish FAQ retrieval evaluation from legal article retrieval and refusal testing.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "193412e761fa",
   "metadata": {},
   "source": [
    "## Stage 09.5 — Enrich the Evaluation Dataset\n",
    "\n",
    "This stage enriches the evaluation dataset by adding two manually designed evaluation groups:\n",
    "\n",
    "1. **Legal article retrieval questions** linked to gold Saudi Labor Law article references.\n",
    "2. **Out-of-scope questions** used to test refusal behaviour and hallucination control.\n",
    "\n",
    "The legal questions are not inserted into the knowledge base. They are used only as evaluation queries. This is essential because adding evaluation questions to the RAG knowledge base would create data leakage and produce unrealistically high retrieval scores.\n",
    "\n",
    "Each legal question is mapped to one or more gold article references using the existing legal article metadata. Any unmatched gold reference should be reviewed before using the dataset in retrieval evaluation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "a75225246826",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluation dataset before enrichment:\n",
      "eval_type\n",
      "faq_retrieval    200\n",
      "Name: count, dtype: int64\n",
      "\n",
      "Evaluation dataset after enrichment:\n",
      "eval_type\n",
      "faq_retrieval              199\n",
      "legal_article_retrieval     24\n",
      "out_of_scope                15\n",
      "Name: count, dtype: int64\n",
      "\n",
      "Counts:\n",
      "FAQ: 199 | Legal: 24 | OOS: 15 | Total: 238\n",
      "\n",
      "كل الأسئلة القانونية طُوبقت بمواد فعّالة بنجاح.\n",
      "\n",
      "Updated evaluation dataset saved:\n",
      "saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 09.5 - Enrich Evaluation Dataset\n",
    "# إضافة أسئلة قانونية وأسئلة خارج النطاق لتقوية التقييم\n",
    "# تعتمد على get_legal_gold المعرّفة في Stage 09 لتوحيد الأعمدة\n",
    "# =========================================================\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Safety checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "assert \"df_eval\" in globals(), \"df_eval must be created in Stage 09 before this cell.\"\n",
    "assert \"get_legal_gold\" in globals(), \"get_legal_gold must be defined in Stage 09 before this cell.\"\n",
    "\n",
    "print(\"Evaluation dataset before enrichment:\")\n",
    "print(df_eval[\"eval_type\"].value_counts(dropna=False))\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Manual legal evaluation questions\n",
    "# راجع أرقام المواد إذا كانت نسخة النظام لديك مختلفة\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "manual_legal_questions = [\n",
    "    {\"question\": \"كم مدة فترة التجربة في نظام العمل السعودي؟\", \"article_numbers\": [53], \"topic\": \"Probation period\"},\n",
    "    {\"question\": \"هل يجوز وضع العامل تحت التجربة أكثر من مرة لدى نفس صاحب العمل؟\", \"article_numbers\": [53], \"topic\": \"Probation repetition\"},\n",
    "    {\"question\": \"ما الحد الأقصى لساعات العمل اليومية في نظام العمل؟\", \"article_numbers\": [98], \"topic\": \"Working hours\"},\n",
    "    {\"question\": \"ما الحد الأقصى لساعات العمل الأسبوعية؟\", \"article_numbers\": [98], \"topic\": \"Weekly working hours\"},\n",
    "    {\"question\": \"هل تختلف ساعات العمل في شهر رمضان؟\", \"article_numbers\": [98], \"topic\": \"Ramadan working hours\"},\n",
    "    {\"question\": \"ما مدة الإجازة السنوية المستحقة للعامل؟\", \"article_numbers\": [109], \"topic\": \"Annual leave\"},\n",
    "    {\"question\": \"متى تزيد الإجازة السنوية إلى ثلاثين يومًا؟\", \"article_numbers\": [109], \"topic\": \"Annual leave duration\"},\n",
    "    {\"question\": \"هل يستحق العامل أجرًا عن أيام الإجازة غير المستخدمة عند انتهاء العمل؟\", \"article_numbers\": [111], \"topic\": \"Unused leave compensation\"},\n",
    "    {\"question\": \"هل يستحق العامل إجازة عند الزواج أو وفاة أحد الأقارب؟\", \"article_numbers\": [113], \"topic\": \"Personal leave\"},\n",
    "    {\"question\": \"هل للعامل الحق في إجازة مرضية؟\", \"article_numbers\": [117], \"topic\": \"Sick leave\"},\n",
    "    {\"question\": \"ما حالات انتهاء عقد العمل؟\", \"article_numbers\": [74], \"topic\": \"Contract termination\"},\n",
    "    {\"question\": \"ما مدة الإشعار عند إنهاء العقد غير محدد المدة؟\", \"article_numbers\": [75], \"topic\": \"Notice period\"},\n",
    "    {\"question\": \"متى يستحق العامل تعويضًا عند إنهاء العقد لسبب غير مشروع؟\", \"article_numbers\": [77], \"topic\": \"Unlawful termination\"},\n",
    "    {\"question\": \"متى يجوز لصاحب العمل إنهاء العقد دون مكافأة أو تعويض؟\", \"article_numbers\": [80], \"topic\": \"Termination without reward\"},\n",
    "    {\"question\": \"متى يجوز للعامل ترك العمل دون إشعار مع احتفاظه بحقوقه؟\", \"article_numbers\": [81], \"topic\": \"Leaving without notice\"},\n",
    "    {\"question\": \"متى يستحق العامل مكافأة نهاية الخدمة؟\", \"article_numbers\": [84, 85], \"topic\": \"End-of-service benefit\"},\n",
    "    {\"question\": \"هل يحق لصاحب العمل نقل العامل من مكان عمله الأصلي؟\", \"article_numbers\": [58], \"topic\": \"Worker transfer\"},\n",
    "    {\"question\": \"ما المقصود بعقد العمل في نظام العمل؟\", \"article_numbers\": [50], \"topic\": \"Contract definition\"},\n",
    "    {\"question\": \"كيف يتم دفع أجر العامل؟\", \"article_numbers\": [90], \"topic\": \"Wage payment\"},\n",
    "    {\"question\": \"ما واجبات صاحب العمل تجاه العامل؟\", \"article_numbers\": [61], \"topic\": \"Employer obligations\"},\n",
    "    {\"question\": \"ما التزامات العامل في نظام العمل؟\", \"article_numbers\": [65], \"topic\": \"Worker obligations\"},\n",
    "    {\"question\": \"ما الحد الأقصى لساعات العمل الإضافية وكيف تُحتسب؟\", \"article_numbers\": [107], \"topic\": \"Overtime\"},\n",
    "    {\"question\": \"ما أحكام السلامة والصحة المهنية في بيئة العمل؟\", \"article_numbers\": [121], \"topic\": \"Occupational safety\"},\n",
    "    {\"question\": \"ما حقوق العاملة في إجازة الوضع؟\", \"article_numbers\": [151], \"topic\": \"Maternity leave\"},\n",
    "]\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Out-of-scope evaluation questions\n",
    "# أسئلة خارج نطاق نظام العمل لاختبار الرفض وعدم الهلوسة\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "manual_oos_questions = [\n",
    "    \"ما حكم الطلاق في الشريعة الإسلامية؟\",\n",
    "    \"كم سعر العقار في الرياض؟\",\n",
    "    \"ما أفضل سيارة عائلية؟\",\n",
    "    \"كيف أفتح مؤسسة تجارية؟\",\n",
    "    \"ما علاج الصداع؟\",\n",
    "    \"كم سعر الذهب اليوم؟\",\n",
    "    \"ما نظام المرور السعودي؟\",\n",
    "    \"اكتب لي قصيدة عن الوطن.\",\n",
    "    \"ما شروط القرض العقاري؟\",\n",
    "    \"ما رسوم الجمارك على السيارات؟\",\n",
    "    \"كيف أستثمر في الأسهم؟\",\n",
    "    \"ما أفضل مطعم في الرياض؟\",\n",
    "    \"ما طريقة استخراج تأشيرة سياحية؟\",\n",
    "    \"ما شروط القبول في الجامعة؟\",\n",
    "    \"من هو أفضل لاعب كرة قدم؟\",\n",
    "]\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Build rows using the SAME schema as Stage 09\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "extra_rows = []\n",
    "\n",
    "for item in manual_legal_questions:\n",
    "    gold = get_legal_gold(item[\"article_numbers\"])\n",
    "    extra_rows.append({\n",
    "        \"question\": item[\"question\"],\n",
    "        \"expected_answer\": gold[\"expected_answer\"],\n",
    "        \"beneficiaries\": \"\",\n",
    "        \"sector\": \"العمل\",\n",
    "        \"subsite\": \"نظام العمل\",\n",
    "        \"legal_category\": item[\"topic\"],\n",
    "        \"source_name\": \"Manual Legal Evaluation\",\n",
    "        \"source_url\": gold[\"source_url\"],\n",
    "        \"eval_type\": \"legal_article_retrieval\",\n",
    "        \"gold_source_type\": \"legal_article\",\n",
    "        \"gold_document_unit_id\": gold[\"gold_document_unit_id\"],\n",
    "        \"gold_document_unit_ids\": gold[\"gold_document_unit_ids\"],\n",
    "        \"gold_article_number\": gold[\"gold_article_number\"],\n",
    "        \"gold_article_numbers\": gold[\"gold_article_numbers\"],\n",
    "        \"gold_article_title\": gold[\"gold_article_title\"],\n",
    "        \"is_out_of_scope\": False,\n",
    "        \"notes\": \"Manual legal question. \" + (gold[\"notes_extra\"] or \"\"),\n",
    "    })\n",
    "\n",
    "for q in manual_oos_questions:\n",
    "    extra_rows.append({\n",
    "        \"question\": q,\n",
    "        \"expected_answer\": \"هذا السؤال خارج نطاق نظام العمل السعودي.\",\n",
    "        \"beneficiaries\": \"\",\n",
    "        \"sector\": \"\",\n",
    "        \"subsite\": \"\",\n",
    "        \"legal_category\": \"Out of Scope\",\n",
    "        \"source_name\": \"Manual Evaluation\",\n",
    "        \"source_url\": \"\",\n",
    "        \"eval_type\": \"out_of_scope\",\n",
    "        \"gold_source_type\": \"\",\n",
    "        \"gold_document_unit_id\": \"\",\n",
    "        \"gold_document_unit_ids\": \"\",\n",
    "        \"gold_article_number\": \"\",\n",
    "        \"gold_article_numbers\": \"\",\n",
    "        \"gold_article_title\": \"\",\n",
    "        \"is_out_of_scope\": True,\n",
    "        \"notes\": \"Out-of-scope rejection test.\",\n",
    "    })\n",
    "\n",
    "df_extra_eval = pd.DataFrame(extra_rows)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Align columns with df_eval (same Stage 09 schema)\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "for col in df_eval.columns:\n",
    "    if col not in df_extra_eval.columns:\n",
    "        df_extra_eval[col] = \"\"\n",
    "\n",
    "df_extra_eval = df_extra_eval[[c for c in df_eval.columns if c != \"eval_id\"]]\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Append, deduplicate, re-number\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_eval = pd.concat(\n",
    "    [df_eval.drop(columns=[\"eval_id\"], errors=\"ignore\"), df_extra_eval],\n",
    "    ignore_index=True\n",
    ")\n",
    "\n",
    "df_eval[\"question\"] = df_eval[\"question\"].fillna(\"\").astype(str).str.strip()\n",
    "df_eval = df_eval.drop_duplicates(subset=[\"question\"], keep=\"first\").reset_index(drop=True)\n",
    "df_eval.insert(0, \"eval_id\", range(1, len(df_eval) + 1))\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 7) Validation\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "legal_count = int((df_eval[\"eval_type\"] == \"legal_article_retrieval\").sum())\n",
    "oos_count = int((df_eval[\"eval_type\"] == \"out_of_scope\").sum())\n",
    "faq_count = int((df_eval[\"eval_type\"] == \"faq_retrieval\").sum())\n",
    "\n",
    "print(\"\\nEvaluation dataset after enrichment:\")\n",
    "print(df_eval[\"eval_type\"].value_counts(dropna=False))\n",
    "print(\"\\nCounts:\")\n",
    "print(\"FAQ:\", faq_count, \"| Legal:\", legal_count, \"| OOS:\", oos_count, \"| Total:\", len(df_eval))\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 8) Warn about unmatched gold articles\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "missing_gold = df_eval[\n",
    "    (df_eval[\"eval_type\"] == \"legal_article_retrieval\") &\n",
    "    (df_eval[\"gold_document_unit_ids\"].astype(str).str.strip() == \"\")\n",
    "]\n",
    "\n",
    "if len(missing_gold) > 0:\n",
    "    print(\"\\nWARNING: بعض الأسئلة القانونية لم تُطابق مادة فعّالة. راجع أرقامها:\")\n",
    "    display(missing_gold[[\"question\", \"gold_article_numbers\", \"legal_category\"]].drop_duplicates())\n",
    "else:\n",
    "    print(\"\\nكل الأسئلة القانونية طُوبقت بمواد فعّالة بنجاح.\")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 9) Save updated evaluation dataset\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "FINAL_DIR.mkdir(parents=True, exist_ok=True)\n",
    "df_eval.to_csv(FINAL_DIR / \"rag_evaluation_dataset.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "df_eval.to_excel(FINAL_DIR / \"rag_evaluation_dataset.xlsx\", index=False)\n",
    "\n",
    "print(\"\\nUpdated evaluation dataset saved:\")\n",
    "print(FINAL_DIR / \"rag_evaluation_dataset.csv\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "2225d4b0-5b16-480a-8b47-b120a06e1ad6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Academic enrichment checks passed successfully.\n"
     ]
    }
   ],
   "source": [
    "# ---------------------------------------------------------\n",
    "# 10) Academic minimum-size checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "assert legal_count >= 20, \"Legal evaluation questions should be at least 20 for stronger academic evaluation.\"\n",
    "assert oos_count >= 10, \"Out-of-scope questions should be at least 10 for reliable refusal testing.\"\n",
    "assert faq_count > 0, \"FAQ evaluation questions must exist.\"\n",
    "assert df_eval[\"question\"].duplicated().sum() == 0, \"Duplicate evaluation questions found.\"\n",
    "\n",
    "allowed_eval_types = {\n",
    "    \"faq_retrieval\",\n",
    "    \"legal_article_retrieval\",\n",
    "    \"out_of_scope\"\n",
    "}\n",
    "\n",
    "unknown_eval_types = set(df_eval[\"eval_type\"].dropna().unique()) - allowed_eval_types\n",
    "assert len(unknown_eval_types) == 0, f\"Unknown eval types found: {unknown_eval_types}\"\n",
    "\n",
    "print(\"Academic enrichment checks passed successfully.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65ec75d1",
   "metadata": {},
   "source": [
    "## Stage 10 — Structural Legal Chunking\n",
    "\n",
    "This stage converts the experimental knowledge base into retrieval chunks using a legal-structure-aware strategy.\n",
    "\n",
    "For legal articles, the article itself is treated as the primary retrieval unit. This preserves the legal context and prevents the article from being split into incomplete fragments. Each legal chunk includes contextual metadata such as the chapter, section, article number, and source information.\n",
    "\n",
    "For non-legal or longer records, controlled splitting is applied only when needed. This approach is more suitable for legal RAG than blind text splitting because legal meaning is often attached to complete article boundaries.\n",
    "\n",
    "**Output:** `rag_chunks_structural_legal_experiment.csv`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "849fbf3511d9",
   "metadata": {},
   "source": [
    "### Structural Chunk Construction\n",
    "\n",
    "This cell builds the structural chunk dataset.\n",
    "\n",
    "The key principle is that each active legal article should remain a coherent retrieval unit whenever possible. The resulting chunks include both the retrievable text and the metadata required for traceability during retrieval evaluation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e387ad9bdf9e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Structural chunks shape: (722, 26)\n",
      "Legal article chunks: 211\n",
      "FAQ chunks: 511\n",
      "\n",
      "Safety checks:\n",
      "Empty chunks: 0\n",
      "Repealed legal chunks: 0\n",
      "FAQ evaluation leakage in chunks: 0\n",
      "\n",
      "Saved:\n",
      "saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.csv\n",
      "saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.xlsx\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 10 - TRUE Structural Chunking (article = one chunk)\n",
    "# كل مادة قانونية مقطع واحد غير مكسور + رأس سياقي\n",
    "# النصوص غير القانونية الطويلة فقط تُقسَّم احتياطياً\n",
    "# =========================================================\n",
    "\n",
    "STRUCTURAL_MAX_WORDS = 350\n",
    "STRUCTURAL_OVERLAP_WORDS = 50\n",
    "\n",
    "CHUNKS_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# Fallback word splitter if Stage 11 has not defined it yet\n",
    "if \"word_chunks\" not in globals():\n",
    "    def word_chunks(text, chunk_size=350, overlap=50):\n",
    "        text = clean_basic_text(text)\n",
    "        words = text.split()\n",
    "        if not words:\n",
    "            return []\n",
    "        if len(words) <= chunk_size:\n",
    "            return [text]\n",
    "        chunks, start = [], 0\n",
    "        while start < len(words):\n",
    "            end = start + chunk_size\n",
    "            chunks.append(\" \".join(words[start:end]))\n",
    "            if end >= len(words):\n",
    "                break\n",
    "            start = max(0, end - overlap)\n",
    "        return chunks\n",
    "\n",
    "\n",
    "def build_structural_context_header(row):\n",
    "    \"\"\"رأس سياقي يربط نص المادة بموقعها في النظام: الباب، الفصل، رقم المادة.\"\"\"\n",
    "    parts = []\n",
    "    if str(row.get(\"bab_title\", \"\")).strip():\n",
    "        parts.append(str(row[\"bab_title\"]).strip())\n",
    "    if str(row.get(\"fasl\", \"\")).strip():\n",
    "        parts.append(str(row[\"fasl\"]).strip())\n",
    "    if str(row.get(\"article_number_label\", \"\")).strip():\n",
    "        parts.append(\"المادة \" + str(row[\"article_number_label\"]))\n",
    "    return \" - \".join(parts)\n",
    "\n",
    "\n",
    "def build_structural_chunks(df_kb, prefix=\"STRUCT\"):\n",
    "    \"\"\"\n",
    "    التقسيم الهيكلي الحقيقي:\n",
    "    - كل مادة قانونية = مقطع واحد غير مكسور + رأس سياقي.\n",
    "    - النصوص غير القانونية الطويلة تُقسَّم احتياطياً حسب عدد الكلمات.\n",
    "    \"\"\"\n",
    "    rows = []\n",
    "    for _, row in df_kb.iterrows():\n",
    "        is_legal = row.get(\"source_type\") == \"legal_article\"\n",
    "\n",
    "        if is_legal:\n",
    "            header = build_structural_context_header(row)\n",
    "            body = clean_basic_text(row[\"text_for_indexing\"])\n",
    "            chunk_text = (header + \"\\n\" + body).strip() if header else body\n",
    "            pieces = [chunk_text]\n",
    "        else:\n",
    "            pieces = word_chunks(\n",
    "                row[\"text_for_indexing\"],\n",
    "                chunk_size=STRUCTURAL_MAX_WORDS,\n",
    "                overlap=STRUCTURAL_OVERLAP_WORDS,\n",
    "            )\n",
    "\n",
    "        for idx, chunk_text in enumerate(pieces, start=1):\n",
    "            rows.append({\n",
    "                \"chunk_id\": f\"{prefix}_{len(rows) + 1:06d}\",\n",
    "                \"chunking_strategy\": \"safe_structural_chunking\",\n",
    "                \"chunk_text\": chunk_text,\n",
    "                \"chunk_word_count\": len(chunk_text.split()),\n",
    "                \"chunk_char_count\": len(chunk_text),\n",
    "                \"chunk_order\": idx,\n",
    "                \"parent_document_id\": row[\"document_unit_id\"],\n",
    "                \"record_id\": row[\"record_id\"],\n",
    "\n",
    "                # Source metadata\n",
    "                \"source_type\": row[\"source_type\"],\n",
    "                \"source_name\": row[\"source_name\"],\n",
    "                \"legal_category\": row[\"legal_category\"],\n",
    "                \"rag_usage\": row.get(\"rag_usage\", \"\"),\n",
    "\n",
    "                # Legal metadata\n",
    "                \"bab_label\": row[\"bab_label\"],\n",
    "                \"bab_title\": row[\"bab_title\"],\n",
    "                \"fasl\": row[\"fasl\"],\n",
    "                \"article_title\": row[\"article_title\"],\n",
    "                \"article_number\": row[\"article_number\"],\n",
    "                \"article_number_label\": row.get(\"article_number_label\", \"\"),\n",
    "                \"article_number_int\": row.get(\"article_number_int\", \"\"),\n",
    "                \"article_status\": row.get(\"article_status\", \"\"),\n",
    "\n",
    "                # FAQ metadata\n",
    "                \"question\": row[\"question\"],\n",
    "                \"answer\": row[\"answer\"],\n",
    "                \"beneficiaries\": row[\"beneficiaries\"],\n",
    "                \"sector\": row[\"sector\"],\n",
    "                \"subsite\": row[\"subsite\"],\n",
    "\n",
    "                # Traceability\n",
    "                \"source_url\": row[\"source_url\"],\n",
    "            })\n",
    "    return pd.DataFrame(rows)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Build structural chunks from experimental KB only\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_structural_chunks = build_structural_chunks(df_kb_experiment, prefix=\"STRUCT\")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Safety checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "structural_empty_chunks = int(\n",
    "    (df_structural_chunks[\"chunk_text\"].astype(str).str.strip() == \"\").sum()\n",
    ")\n",
    "structural_repealed_chunks = int(\n",
    "    (\n",
    "        (df_structural_chunks[\"source_type\"] == \"legal_article\") &\n",
    "        (df_structural_chunks[\"article_status\"] == \"repealed\")\n",
    "    ).sum()\n",
    ")\n",
    "structural_faq_eval_leakage = len(\n",
    "    set(df_structural_chunks[df_structural_chunks[\"source_type\"] == \"faq\"][\"parent_document_id\"])\n",
    "    & set(df_faq_evaluation[\"document_unit_id\"])\n",
    ")\n",
    "\n",
    "assert structural_empty_chunks == 0, \"Error: Empty chunks created in structural chunking.\"\n",
    "assert structural_repealed_chunks == 0, \"Error: Repealed legal articles found inside structural chunks.\"\n",
    "assert structural_faq_eval_leakage == 0, \"Error: FAQ evaluation records leaked into structural chunks.\"\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Save outputs\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "structural_csv_path = CHUNKS_DIR / \"rag_chunks_structural_legal_experiment.csv\"\n",
    "structural_xlsx_path = CHUNKS_DIR / \"rag_chunks_structural_legal_experiment.xlsx\"\n",
    "\n",
    "df_structural_chunks.to_csv(structural_csv_path, index=False, encoding=\"utf-8-sig\")\n",
    "df_structural_chunks.to_excel(structural_xlsx_path, index=False)\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Summary\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "print(\"Structural chunks shape:\", df_structural_chunks.shape)\n",
    "print(\"Legal article chunks:\", int((df_structural_chunks[\"source_type\"] == \"legal_article\").sum()))\n",
    "print(\"FAQ chunks:\", int((df_structural_chunks[\"source_type\"] == \"faq\").sum()))\n",
    "print(\"\\nSafety checks:\")\n",
    "print(\"Empty chunks:\", structural_empty_chunks)\n",
    "print(\"Repealed legal chunks:\", structural_repealed_chunks)\n",
    "print(\"FAQ evaluation leakage in chunks:\", structural_faq_eval_leakage)\n",
    "print(\"\\nSaved:\")\n",
    "print(structural_csv_path)\n",
    "print(structural_xlsx_path)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "db0f3fb9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_6a29d caption {\n",
       "  font-weight: bold;\n",
       "  font-size: 14px;\n",
       "  color: #1F4E78;\n",
       "  text-align: right;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_6a29d th {\n",
       "  background-color: #1F4E78;\n",
       "  color: white;\n",
       "  text-align: right;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_6a29d td {\n",
       "  border: 1px solid #ddd;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_6a29d  {\n",
       "  direction: rtl;\n",
       "  border-collapse: collapse;\n",
       "}\n",
       "#T_6a29d_row0_col0, #T_6a29d_row1_col0, #T_6a29d_row2_col0, #T_6a29d_row3_col0 {\n",
       "  text-align: right;\n",
       "  font-size: 13px;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_6a29d\">\n",
       "  <caption>ملخص التقسيم الهيكلي</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_6a29d_level0_col0\" class=\"col_heading level0 col0\" >القيمة</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_6a29d_level0_row0\" class=\"row_heading level0 row0\" >إجمالي المقاطع</th>\n",
       "      <td id=\"T_6a29d_row0_col0\" class=\"data row0 col0\" >722.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6a29d_level0_row1\" class=\"row_heading level0 row1\" >مقاطع قانونية</th>\n",
       "      <td id=\"T_6a29d_row1_col0\" class=\"data row1 col0\" >211.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6a29d_level0_row2\" class=\"row_heading level0 row2\" >مقاطع شائعة/دليل</th>\n",
       "      <td id=\"T_6a29d_row2_col0\" class=\"data row2 col0\" >511.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_6a29d_level0_row3\" class=\"row_heading level0 row3\" >متوسط كلمات المقطع</th>\n",
       "      <td id=\"T_6a29d_row3_col0\" class=\"data row3 col0\" >85.400000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa207cc910>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_247bb caption {\n",
       "  font-weight: bold;\n",
       "  font-size: 14px;\n",
       "  color: #1F4E78;\n",
       "  text-align: right;\n",
       "  padding: 6px;\n",
       "}\n",
       "#T_247bb th {\n",
       "  background-color: #1F4E78;\n",
       "  color: white;\n",
       "  text-align: right;\n",
       "  padding: 8px;\n",
       "  font-size: 13px;\n",
       "}\n",
       "#T_247bb td {\n",
       "  border: 1px solid #e0e0e0;\n",
       "  padding: 8px;\n",
       "}\n",
       "#T_247bb tr:nth-child(even) td {\n",
       "  background-color: #f5f8fc;\n",
       "}\n",
       "#T_247bb  {\n",
       "  direction: rtl;\n",
       "  border-collapse: collapse;\n",
       "}\n",
       "#T_247bb_row0_col0, #T_247bb_row0_col1, #T_247bb_row0_col2, #T_247bb_row0_col3, #T_247bb_row0_col4, #T_247bb_row1_col0, #T_247bb_row1_col1, #T_247bb_row1_col2, #T_247bb_row1_col3, #T_247bb_row1_col4, #T_247bb_row2_col0, #T_247bb_row2_col1, #T_247bb_row2_col2, #T_247bb_row2_col3, #T_247bb_row2_col4, #T_247bb_row3_col0, #T_247bb_row3_col1, #T_247bb_row3_col2, #T_247bb_row3_col3, #T_247bb_row3_col4, #T_247bb_row4_col0, #T_247bb_row4_col1, #T_247bb_row4_col2, #T_247bb_row4_col3, #T_247bb_row4_col4 {\n",
       "  text-align: right;\n",
       "  font-size: 13px;\n",
       "  white-space: normal;\n",
       "  vertical-align: top;\n",
       "}\n",
       "#T_247bb_row0_col5, #T_247bb_row1_col5, #T_247bb_row2_col5, #T_247bb_row3_col5, #T_247bb_row4_col5 {\n",
       "  text-align: right;\n",
       "  font-size: 13px;\n",
       "  white-space: normal;\n",
       "  vertical-align: top;\n",
       "  min-width: 380px;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_247bb\">\n",
       "  <caption>معاينة أول خمسة مقاطع</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th id=\"T_247bb_level0_col0\" class=\"col_heading level0 col0\" >رقم المقطع</th>\n",
       "      <th id=\"T_247bb_level0_col1\" class=\"col_heading level0 col1\" >نوع المصدر</th>\n",
       "      <th id=\"T_247bb_level0_col2\" class=\"col_heading level0 col2\" >رقم المادة</th>\n",
       "      <th id=\"T_247bb_level0_col3\" class=\"col_heading level0 col3\" >عدد الكلمات</th>\n",
       "      <th id=\"T_247bb_level0_col4\" class=\"col_heading level0 col4\" >عدد الأحرف</th>\n",
       "      <th id=\"T_247bb_level0_col5\" class=\"col_heading level0 col5\" >معاينة النص</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td id=\"T_247bb_row0_col0\" class=\"data row0 col0\" >STRUCT_000001</td>\n",
       "      <td id=\"T_247bb_row0_col1\" class=\"data row0 col1\" >legal_article</td>\n",
       "      <td id=\"T_247bb_row0_col2\" class=\"data row0 col2\" >1</td>\n",
       "      <td id=\"T_247bb_row0_col3\" class=\"data row0 col3\" >37</td>\n",
       "      <td id=\"T_247bb_row0_col4\" class=\"data row0 col4\" >214</td>\n",
       "      <td id=\"T_247bb_row0_col5\" class=\"data row0 col5\" >التعريفات / الأحكام العامة - الفصل الأول - المادة 1 المصدر: نظام العمل السعودي الباب الأول - ال …</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td id=\"T_247bb_row1_col0\" class=\"data row1 col0\" >STRUCT_000002</td>\n",
       "      <td id=\"T_247bb_row1_col1\" class=\"data row1 col1\" >legal_article</td>\n",
       "      <td id=\"T_247bb_row1_col2\" class=\"data row1 col2\" >2</td>\n",
       "      <td id=\"T_247bb_row1_col3\" class=\"data row1 col3\" >653</td>\n",
       "      <td id=\"T_247bb_row1_col4\" class=\"data row1 col4\" >3708</td>\n",
       "      <td id=\"T_247bb_row1_col5\" class=\"data row1 col5\" >التعريفات / الأحكام العامة - الفصل الأول - المادة 2 المصدر: نظام العمل السعودي الباب الأول - ال …</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td id=\"T_247bb_row2_col0\" class=\"data row2 col0\" >STRUCT_000003</td>\n",
       "      <td id=\"T_247bb_row2_col1\" class=\"data row2 col1\" >legal_article</td>\n",
       "      <td id=\"T_247bb_row2_col2\" class=\"data row2 col2\" >3</td>\n",
       "      <td id=\"T_247bb_row2_col3\" class=\"data row2 col3\" >82</td>\n",
       "      <td id=\"T_247bb_row2_col4\" class=\"data row2 col4\" >448</td>\n",
       "      <td id=\"T_247bb_row2_col5\" class=\"data row2 col5\" >التعريفات / الأحكام العامة - الفصل الثاني - المادة 3 المصدر: نظام العمل السعودي الباب الأول - ا …</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td id=\"T_247bb_row3_col0\" class=\"data row3 col0\" >STRUCT_000004</td>\n",
       "      <td id=\"T_247bb_row3_col1\" class=\"data row3 col1\" >legal_article</td>\n",
       "      <td id=\"T_247bb_row3_col2\" class=\"data row3 col2\" >4</td>\n",
       "      <td id=\"T_247bb_row3_col3\" class=\"data row3 col3\" >48</td>\n",
       "      <td id=\"T_247bb_row3_col4\" class=\"data row3 col4\" >287</td>\n",
       "      <td id=\"T_247bb_row3_col5\" class=\"data row3 col5\" >التعريفات / الأحكام العامة - الفصل الثاني - المادة 4 المصدر: نظام العمل السعودي الباب الأول - ا …</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td id=\"T_247bb_row4_col0\" class=\"data row4 col0\" >STRUCT_000005</td>\n",
       "      <td id=\"T_247bb_row4_col1\" class=\"data row4 col1\" >legal_article</td>\n",
       "      <td id=\"T_247bb_row4_col2\" class=\"data row4 col2\" >5</td>\n",
       "      <td id=\"T_247bb_row4_col3\" class=\"data row4 col3\" >110</td>\n",
       "      <td id=\"T_247bb_row4_col4\" class=\"data row4 col4\" >623</td>\n",
       "      <td id=\"T_247bb_row4_col5\" class=\"data row4 col5\" >التعريفات / الأحكام العامة - الفصل الثاني - المادة 5 المصدر: نظام العمل السعودي الباب الأول - ا …</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa207cc910>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# =========================================================\n",
    "# معاينة احترافية للمقاطع داخل النوتبوك (للعرض فقط)\n",
    "# الملف المحفوظ يبقى بالأعمدة الإنجليزية كما هو\n",
    "# =========================================================\n",
    "\n",
    "n_total = len(df_structural_chunks)\n",
    "n_legal = int((df_structural_chunks[\"source_type\"] == \"legal_article\").sum())\n",
    "n_faq = n_total - n_legal\n",
    "avg_words = round(df_structural_chunks[\"chunk_word_count\"].mean(), 1)\n",
    "\n",
    "summary = pd.DataFrame(\n",
    "    {\n",
    "        \"القيمة\": [n_total, n_legal, n_faq, avg_words],\n",
    "    },\n",
    "    index=[\"إجمالي المقاطع\", \"مقاطع قانونية\", \"مقاطع شائعة/دليل\", \"متوسط كلمات المقطع\"],\n",
    ")\n",
    "display(\n",
    "    summary.style\n",
    "    .set_caption(\"ملخص التقسيم الهيكلي\")\n",
    "    .set_properties(**{\"text-align\": \"right\", \"font-size\": \"13px\"})\n",
    "    .set_table_styles([\n",
    "        {\"selector\": \"caption\", \"props\": [(\"font-weight\", \"bold\"), (\"font-size\", \"14px\"),\n",
    "                                          (\"color\", \"#1F4E78\"), (\"text-align\", \"right\"),\n",
    "                                          (\"padding\", \"6px\")]},\n",
    "        {\"selector\": \"th\", \"props\": [(\"background-color\", \"#1F4E78\"), (\"color\", \"white\"),\n",
    "                                     (\"text-align\", \"right\"), (\"padding\", \"8px\")]},\n",
    "        {\"selector\": \"td\", \"props\": [(\"border\", \"1px solid #ddd\"), (\"padding\", \"8px\")]},\n",
    "        {\"selector\": \"\", \"props\": [(\"direction\", \"rtl\"), (\"border-collapse\", \"collapse\")]},\n",
    "    ])\n",
    ")\n",
    "\n",
    "# معاينة أنيقة لأول مقاطع\n",
    "preview_cols = {\n",
    "    \"chunk_id\": \"رقم المقطع\",\n",
    "    \"source_type\": \"نوع المصدر\",\n",
    "    \"article_number_label\": \"رقم المادة\",\n",
    "    \"chunk_word_count\": \"عدد الكلمات\",\n",
    "    \"chunk_char_count\": \"عدد الأحرف\",\n",
    "    \"chunk_text\": \"معاينة النص\",\n",
    "}\n",
    "\n",
    "prev = df_structural_chunks[list(preview_cols)].head(5).copy()\n",
    "prev[\"chunk_text\"] = (\n",
    "    prev[\"chunk_text\"].astype(str)\n",
    "    .str.replace(\"\\n\", \" \", regex=False)\n",
    "    .str.slice(0, 95)\n",
    "    .str.rstrip() + \" …\"\n",
    ")\n",
    "prev = prev.rename(columns=preview_cols)\n",
    "\n",
    "(\n",
    "    prev.style\n",
    "    .hide(axis=\"index\")\n",
    "    .set_caption(\"معاينة أول خمسة مقاطع\")\n",
    "    .set_properties(**{\"text-align\": \"right\", \"font-size\": \"13px\",\n",
    "                       \"white-space\": \"normal\", \"vertical-align\": \"top\"})\n",
    "    .set_properties(subset=[\"معاينة النص\"], **{\"min-width\": \"380px\"})\n",
    "    .set_table_styles([\n",
    "        {\"selector\": \"caption\", \"props\": [(\"font-weight\", \"bold\"), (\"font-size\", \"14px\"),\n",
    "                                          (\"color\", \"#1F4E78\"), (\"text-align\", \"right\"),\n",
    "                                          (\"padding\", \"6px\")]},\n",
    "        {\"selector\": \"th\", \"props\": [(\"background-color\", \"#1F4E78\"), (\"color\", \"white\"),\n",
    "                                     (\"text-align\", \"right\"), (\"padding\", \"8px\"),\n",
    "                                     (\"font-size\", \"13px\")]},\n",
    "        {\"selector\": \"td\", \"props\": [(\"border\", \"1px solid #e0e0e0\"), (\"padding\", \"8px\")]},\n",
    "        {\"selector\": \"tr:nth-child(even) td\", \"props\": [(\"background-color\", \"#f5f8fc\")]},\n",
    "        {\"selector\": \"\", \"props\": [(\"direction\", \"rtl\"), (\"border-collapse\", \"collapse\")]},\n",
    "    ])\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6359ecc-aedf-4970-b65b-ef5c40028d02",
   "metadata": {},
   "source": [
    "### Interpretation — Structural Chunking Quality\n",
    "\n",
    "The structural chunking summary evaluates whether the generated chunks are suitable for legal retrieval.\n",
    "\n",
    "The main quality indicators are:\n",
    "\n",
    "- The total number of generated chunks.\n",
    "- The distribution of chunks by source type.\n",
    "- The absence of empty chunks.\n",
    "- The absence of chunks derived from repealed legal articles.\n",
    "- The absence of leaked FAQ evaluation records inside the chunked indexing data.\n",
    "\n",
    "A successful result indicates that the structural chunking strategy preserves legal traceability while maintaining a safe retrieval corpus for the next RAG stage.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10728696",
   "metadata": {},
   "source": [
    "## Stage 11 — Fixed-Size Chunking Baseline\n",
    "\n",
    "This stage builds a fixed-size chunking baseline for comparison with structural legal chunking.\n",
    "\n",
    "Unlike structural chunking, fixed-size chunking divides text according to a maximum word length and overlap. It does not explicitly respect legal article boundaries. This makes it useful as a baseline because it represents a common general-purpose text splitting approach.\n",
    "\n",
    "The comparison between fixed-size and structural chunking helps determine whether preserving legal structure improves retrieval quality in the next stage.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "bb7ab993",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fixed-size chunks shape: (719, 26)\n",
      "Fixed chunk size words: 500\n",
      "Fixed overlap words: 80\n",
      "\n",
      "Safety checks:\n",
      "Empty chunks: 0\n",
      "Repealed legal chunks: 0\n",
      "FAQ evaluation leakage in chunks: 0\n",
      "\n",
      "Chunks by source_type:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>source_type</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>faq</th>\n",
       "      <td>507</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>legal_article</th>\n",
       "      <td>212</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               count\n",
       "source_type         \n",
       "faq              507\n",
       "legal_article    212"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Fixed-size chunk length statistics:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>chunk_word_count</th>\n",
       "      <th>chunk_char_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>719.00</td>\n",
       "      <td>719.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>83.02</td>\n",
       "      <td>480.64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>59.27</td>\n",
       "      <td>325.42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>27.00</td>\n",
       "      <td>162.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>50.00</td>\n",
       "      <td>296.50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>68.00</td>\n",
       "      <td>406.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>94.00</td>\n",
       "      <td>551.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>500.00</td>\n",
       "      <td>2872.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       chunk_word_count  chunk_char_count\n",
       "count            719.00            719.00\n",
       "mean              83.02            480.64\n",
       "std               59.27            325.42\n",
       "min               27.00            162.00\n",
       "25%               50.00            296.50\n",
       "50%               68.00            406.00\n",
       "75%               94.00            551.00\n",
       "max              500.00           2872.00"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Saved:\n",
      "saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.csv\n",
      "saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.xlsx\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 11 - Fixed-size Chunking Baseline\n",
    "# خط أساس للمقارنة مع Structural Chunking\n",
    "# =========================================================\n",
    "\n",
    "CHUNK_SIZE_WORDS = 500\n",
    "CHUNK_OVERLAP_WORDS = 80\n",
    "\n",
    "CHUNKS_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# Fallback if this cell is run independently\n",
    "if \"word_chunks\" not in globals():\n",
    "    def word_chunks(text, chunk_size=500, overlap=80):\n",
    "        text = clean_basic_text(text)\n",
    "        words = text.split()\n",
    "\n",
    "        if not words:\n",
    "            return []\n",
    "\n",
    "        if len(words) <= chunk_size:\n",
    "            return [text]\n",
    "\n",
    "        chunks = []\n",
    "        start = 0\n",
    "\n",
    "        while start < len(words):\n",
    "            end = start + chunk_size\n",
    "            chunks.append(\" \".join(words[start:end]))\n",
    "\n",
    "            if end >= len(words):\n",
    "                break\n",
    "\n",
    "            start = max(0, end - overlap)\n",
    "\n",
    "        return chunks\n",
    "\n",
    "\n",
    "def build_fixed_chunks(df_kb, chunk_size=500, overlap=80, prefix=\"FIXED\"):\n",
    "    rows = []\n",
    "\n",
    "    for _, row in df_kb.iterrows():\n",
    "        chunks = word_chunks(\n",
    "            row[\"text_for_indexing\"],\n",
    "            chunk_size=chunk_size,\n",
    "            overlap=overlap\n",
    "        )\n",
    "\n",
    "        for idx, chunk_text in enumerate(chunks, start=1):\n",
    "            rows.append({\n",
    "                \"chunk_id\": f\"{prefix}_{len(rows) + 1:06d}\",\n",
    "                \"chunking_strategy\": \"fixed_size_chunking_baseline\",\n",
    "                \"chunk_text\": chunk_text,\n",
    "                \"chunk_word_count\": len(chunk_text.split()),\n",
    "                \"chunk_char_count\": len(chunk_text),\n",
    "                \"chunk_order\": idx,\n",
    "                \"parent_document_id\": row[\"document_unit_id\"],\n",
    "                \"record_id\": row[\"record_id\"],\n",
    "\n",
    "                # Source metadata\n",
    "                \"source_type\": row[\"source_type\"],\n",
    "                \"source_name\": row[\"source_name\"],\n",
    "                \"legal_category\": row[\"legal_category\"],\n",
    "                \"rag_usage\": row.get(\"rag_usage\", \"\"),\n",
    "\n",
    "                # Legal metadata\n",
    "                \"bab_label\": row[\"bab_label\"],\n",
    "                \"bab_title\": row[\"bab_title\"],\n",
    "                \"fasl\": row[\"fasl\"],\n",
    "                \"article_title\": row[\"article_title\"],\n",
    "                \"article_number\": row[\"article_number\"],\n",
    "                \"article_number_label\": row.get(\"article_number_label\", \"\"),\n",
    "                \"article_number_int\": row.get(\"article_number_int\", \"\"),\n",
    "                \"article_status\": row.get(\"article_status\", \"\"),\n",
    "\n",
    "                # FAQ metadata\n",
    "                \"question\": row[\"question\"],\n",
    "                \"answer\": row[\"answer\"],\n",
    "                \"beneficiaries\": row[\"beneficiaries\"],\n",
    "                \"sector\": row[\"sector\"],\n",
    "                \"subsite\": row[\"subsite\"],\n",
    "\n",
    "                # Traceability\n",
    "                \"source_url\": row[\"source_url\"],\n",
    "            })\n",
    "\n",
    "    return pd.DataFrame(rows)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Build fixed-size baseline chunks from experimental KB only\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_fixed_chunks = build_fixed_chunks(\n",
    "    df_kb_experiment,\n",
    "    chunk_size=CHUNK_SIZE_WORDS,\n",
    "    overlap=CHUNK_OVERLAP_WORDS,\n",
    "    prefix=\"FIXED\"\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Safety checks\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "fixed_empty_chunks = int(\n",
    "    (df_fixed_chunks[\"chunk_text\"].astype(str).str.strip() == \"\").sum()\n",
    ")\n",
    "\n",
    "fixed_repealed_chunks = int(\n",
    "    (\n",
    "        (df_fixed_chunks[\"source_type\"] == \"legal_article\") &\n",
    "        (df_fixed_chunks[\"article_status\"] == \"repealed\")\n",
    "    ).sum()\n",
    ")\n",
    "\n",
    "fixed_faq_eval_leakage = len(\n",
    "    set(\n",
    "        df_fixed_chunks[\n",
    "            df_fixed_chunks[\"source_type\"] == \"faq\"\n",
    "        ][\"parent_document_id\"]\n",
    "    )\n",
    "    &\n",
    "    set(df_faq_evaluation[\"document_unit_id\"])\n",
    ")\n",
    "\n",
    "assert fixed_empty_chunks == 0, \"Error: Empty chunks were created in fixed-size baseline.\"\n",
    "assert fixed_repealed_chunks == 0, \"Error: Repealed legal articles found inside fixed-size chunks.\"\n",
    "assert fixed_faq_eval_leakage == 0, \"Error: FAQ evaluation records leaked into fixed-size chunks.\"\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Save outputs\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "fixed_csv_path = CHUNKS_DIR / \"rag_chunks_fixed_size_experiment.csv\"\n",
    "fixed_xlsx_path = CHUNKS_DIR / \"rag_chunks_fixed_size_experiment.xlsx\"\n",
    "\n",
    "df_fixed_chunks.to_csv(\n",
    "    fixed_csv_path,\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "df_fixed_chunks.to_excel(\n",
    "    fixed_xlsx_path,\n",
    "    index=False\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# Summary\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "print(\"Fixed-size chunks shape:\", df_fixed_chunks.shape)\n",
    "print(\"Fixed chunk size words:\", CHUNK_SIZE_WORDS)\n",
    "print(\"Fixed overlap words:\", CHUNK_OVERLAP_WORDS)\n",
    "\n",
    "print(\"\\nSafety checks:\")\n",
    "print(\"Empty chunks:\", fixed_empty_chunks)\n",
    "print(\"Repealed legal chunks:\", fixed_repealed_chunks)\n",
    "print(\"FAQ evaluation leakage in chunks:\", fixed_faq_eval_leakage)\n",
    "\n",
    "print(\"\\nChunks by source_type:\")\n",
    "display(df_fixed_chunks[\"source_type\"].value_counts().to_frame(\"count\"))\n",
    "\n",
    "print(\"\\nFixed-size chunk length statistics:\")\n",
    "display(\n",
    "    df_fixed_chunks[[\"chunk_word_count\", \"chunk_char_count\"]]\n",
    "    .describe()\n",
    "    .round(2)\n",
    ")\n",
    "\n",
    "print(\"\\nSaved:\")\n",
    "print(fixed_csv_path)\n",
    "print(fixed_xlsx_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a68a2442-cc21-40f8-8454-70dddc30195f",
   "metadata": {},
   "source": [
    "### Interpretation — Fixed-Size Chunking Baseline\n",
    "\n",
    "The fixed-size chunking output provides a baseline against which the structural legal chunking strategy can be compared.\n",
    "\n",
    "This baseline is important because it shows how a standard chunking method behaves on the same knowledge base. If the legal-structure-aware method performs better during retrieval evaluation, the improvement can be attributed to preserving the structure of legal articles rather than to differences in the source data.\n",
    "\n",
    "The quality checks should confirm that fixed-size chunks are non-empty, traceable to their source records, and free from repealed legal articles and evaluation leakage.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bb0a2bc",
   "metadata": {},
   "source": [
    "## Stage 12 — Post-Chunking Quality Checks\n",
    "\n",
    "This stage validates the chunk files before they are passed to the embedding and retrieval notebook.\n",
    "\n",
    "The checks verify that each chunk contains text, has a unique chunk identifier, and preserves the required metadata linking it back to the original source record. This traceability is necessary for calculating retrieval metrics such as article hit rate and for diagnosing retrieval errors.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e18d469e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_f3bc0 th {\n",
       "  text-align: center;\n",
       "  font-weight: bold;\n",
       "  background-color: #f2f2f2;\n",
       "}\n",
       "#T_f3bc0 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "}\n",
       "#T_f3bc0_row0_col0, #T_f3bc0_row0_col1, #T_f3bc0_row0_col2, #T_f3bc0_row0_col3, #T_f3bc0_row0_col4, #T_f3bc0_row1_col0, #T_f3bc0_row1_col1, #T_f3bc0_row1_col2, #T_f3bc0_row1_col3, #T_f3bc0_row1_col4, #T_f3bc0_row2_col0, #T_f3bc0_row2_col1, #T_f3bc0_row2_col2, #T_f3bc0_row2_col3, #T_f3bc0_row2_col4, #T_f3bc0_row3_col0, #T_f3bc0_row3_col1, #T_f3bc0_row3_col2, #T_f3bc0_row3_col3, #T_f3bc0_row3_col4, #T_f3bc0_row4_col0, #T_f3bc0_row4_col1, #T_f3bc0_row4_col2, #T_f3bc0_row4_col3, #T_f3bc0_row4_col4, #T_f3bc0_row5_col0, #T_f3bc0_row5_col1, #T_f3bc0_row5_col2, #T_f3bc0_row5_col3, #T_f3bc0_row5_col4, #T_f3bc0_row6_col0, #T_f3bc0_row6_col1, #T_f3bc0_row6_col2, #T_f3bc0_row6_col3, #T_f3bc0_row6_col4, #T_f3bc0_row7_col0, #T_f3bc0_row7_col1, #T_f3bc0_row7_col2, #T_f3bc0_row7_col3, #T_f3bc0_row7_col4, #T_f3bc0_row8_col0, #T_f3bc0_row8_col1, #T_f3bc0_row8_col2, #T_f3bc0_row8_col3, #T_f3bc0_row8_col4, #T_f3bc0_row9_col0, #T_f3bc0_row9_col1, #T_f3bc0_row9_col2, #T_f3bc0_row9_col3, #T_f3bc0_row9_col4, #T_f3bc0_row10_col0, #T_f3bc0_row10_col1, #T_f3bc0_row10_col2, #T_f3bc0_row10_col3, #T_f3bc0_row10_col4, #T_f3bc0_row11_col0, #T_f3bc0_row11_col1, #T_f3bc0_row11_col2, #T_f3bc0_row11_col3, #T_f3bc0_row11_col4, #T_f3bc0_row12_col0, #T_f3bc0_row12_col1, #T_f3bc0_row12_col2, #T_f3bc0_row12_col3, #T_f3bc0_row12_col4, #T_f3bc0_row13_col0, #T_f3bc0_row13_col1, #T_f3bc0_row13_col2, #T_f3bc0_row13_col3, #T_f3bc0_row13_col4, #T_f3bc0_row14_col0, #T_f3bc0_row14_col1, #T_f3bc0_row14_col2, #T_f3bc0_row14_col3, #T_f3bc0_row14_col4, #T_f3bc0_row15_col0, #T_f3bc0_row15_col1, #T_f3bc0_row15_col2, #T_f3bc0_row15_col3, #T_f3bc0_row15_col4, #T_f3bc0_row16_col0, #T_f3bc0_row16_col1, #T_f3bc0_row16_col2, #T_f3bc0_row16_col3, #T_f3bc0_row16_col4, #T_f3bc0_row17_col0, #T_f3bc0_row17_col1, #T_f3bc0_row17_col2, #T_f3bc0_row17_col3, #T_f3bc0_row17_col4, #T_f3bc0_row18_col0, #T_f3bc0_row18_col1, #T_f3bc0_row18_col2, #T_f3bc0_row18_col3, #T_f3bc0_row18_col4, #T_f3bc0_row19_col0, #T_f3bc0_row19_col1, #T_f3bc0_row19_col2, #T_f3bc0_row19_col3, #T_f3bc0_row19_col4, #T_f3bc0_row20_col0, #T_f3bc0_row20_col1, #T_f3bc0_row20_col2, #T_f3bc0_row20_col3, #T_f3bc0_row20_col4, #T_f3bc0_row21_col0, #T_f3bc0_row21_col1, #T_f3bc0_row21_col2, #T_f3bc0_row21_col3, #T_f3bc0_row21_col4 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_f3bc0\">\n",
       "  <caption>Chunk Quality Report</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_f3bc0_level0_col0\" class=\"col_heading level0 col0\" >strategy</th>\n",
       "      <th id=\"T_f3bc0_level0_col1\" class=\"col_heading level0 col1\" >check</th>\n",
       "      <th id=\"T_f3bc0_level0_col2\" class=\"col_heading level0 col2\" >value</th>\n",
       "      <th id=\"T_f3bc0_level0_col3\" class=\"col_heading level0 col3\" >status</th>\n",
       "      <th id=\"T_f3bc0_level0_col4\" class=\"col_heading level0 col4\" >interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_f3bc0_row0_col0\" class=\"data row0 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row0_col1\" class=\"data row0 col1\" >Total chunks</td>\n",
       "      <td id=\"T_f3bc0_row0_col2\" class=\"data row0 col2\" >722.000000</td>\n",
       "      <td id=\"T_f3bc0_row0_col3\" class=\"data row0 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row0_col4\" class=\"data row0 col4\" >Total number of generated chunks.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_f3bc0_row1_col0\" class=\"data row1 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row1_col1\" class=\"data row1 col1\" >Legal article chunks</td>\n",
       "      <td id=\"T_f3bc0_row1_col2\" class=\"data row1 col2\" >211.000000</td>\n",
       "      <td id=\"T_f3bc0_row1_col3\" class=\"data row1 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row1_col4\" class=\"data row1 col4\" >Chunks generated from active legal articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_f3bc0_row2_col0\" class=\"data row2 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row2_col1\" class=\"data row2 col1\" >FAQ chunks</td>\n",
       "      <td id=\"T_f3bc0_row2_col2\" class=\"data row2 col2\" >511.000000</td>\n",
       "      <td id=\"T_f3bc0_row2_col3\" class=\"data row2 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row2_col4\" class=\"data row2 col4\" >Chunks generated from FAQ indexing records.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_f3bc0_row3_col0\" class=\"data row3 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row3_col1\" class=\"data row3 col1\" >Empty chunk_text</td>\n",
       "      <td id=\"T_f3bc0_row3_col2\" class=\"data row3 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row3_col3\" class=\"data row3 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row3_col4\" class=\"data row3 col4\" >Empty chunks should not exist.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
       "      <td id=\"T_f3bc0_row4_col0\" class=\"data row4 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row4_col1\" class=\"data row4 col1\" >Missing parent_document_id</td>\n",
       "      <td id=\"T_f3bc0_row4_col2\" class=\"data row4 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row4_col3\" class=\"data row4 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row4_col4\" class=\"data row4 col4\" >Every chunk must link to a source record.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
       "      <td id=\"T_f3bc0_row5_col0\" class=\"data row5 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row5_col1\" class=\"data row5 col1\" >Duplicated chunk_id</td>\n",
       "      <td id=\"T_f3bc0_row5_col2\" class=\"data row5 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row5_col3\" class=\"data row5 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row5_col4\" class=\"data row5 col4\" >Chunk IDs must be unique.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
       "      <td id=\"T_f3bc0_row6_col0\" class=\"data row6 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row6_col1\" class=\"data row6 col1\" >Repealed legal chunks</td>\n",
       "      <td id=\"T_f3bc0_row6_col2\" class=\"data row6 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row6_col3\" class=\"data row6 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row6_col4\" class=\"data row6 col4\" >Must be zero to avoid retrieving repealed legal provisions.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
       "      <td id=\"T_f3bc0_row7_col0\" class=\"data row7 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row7_col1\" class=\"data row7 col1\" >FAQ evaluation leakage in chunks</td>\n",
       "      <td id=\"T_f3bc0_row7_col2\" class=\"data row7 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row7_col3\" class=\"data row7 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row7_col4\" class=\"data row7 col4\" >Must be zero to avoid evaluation leakage.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
       "      <td id=\"T_f3bc0_row8_col0\" class=\"data row8 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row8_col1\" class=\"data row8 col1\" >Mean words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row8_col2\" class=\"data row8 col2\" >85.430000</td>\n",
       "      <td id=\"T_f3bc0_row8_col3\" class=\"data row8 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row8_col4\" class=\"data row8 col4\" >Average retrieval granularity.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
       "      <td id=\"T_f3bc0_row9_col0\" class=\"data row9 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row9_col1\" class=\"data row9 col1\" >Median words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row9_col2\" class=\"data row9 col2\" >72.000000</td>\n",
       "      <td id=\"T_f3bc0_row9_col3\" class=\"data row9 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row9_col4\" class=\"data row9 col4\" >Median retrieval granularity.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row10\" class=\"row_heading level0 row10\" >10</th>\n",
       "      <td id=\"T_f3bc0_row10_col0\" class=\"data row10 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_f3bc0_row10_col1\" class=\"data row10 col1\" >Max words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row10_col2\" class=\"data row10 col2\" >653.000000</td>\n",
       "      <td id=\"T_f3bc0_row10_col3\" class=\"data row10 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row10_col4\" class=\"data row10 col4\" >Structural chunking keeps each article intact; exceeding 350 words is expected for long articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row11\" class=\"row_heading level0 row11\" >11</th>\n",
       "      <td id=\"T_f3bc0_row11_col0\" class=\"data row11 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row11_col1\" class=\"data row11 col1\" >Total chunks</td>\n",
       "      <td id=\"T_f3bc0_row11_col2\" class=\"data row11 col2\" >719.000000</td>\n",
       "      <td id=\"T_f3bc0_row11_col3\" class=\"data row11 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row11_col4\" class=\"data row11 col4\" >Total number of generated chunks.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row12\" class=\"row_heading level0 row12\" >12</th>\n",
       "      <td id=\"T_f3bc0_row12_col0\" class=\"data row12 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row12_col1\" class=\"data row12 col1\" >Legal article chunks</td>\n",
       "      <td id=\"T_f3bc0_row12_col2\" class=\"data row12 col2\" >212.000000</td>\n",
       "      <td id=\"T_f3bc0_row12_col3\" class=\"data row12 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row12_col4\" class=\"data row12 col4\" >Chunks generated from active legal articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row13\" class=\"row_heading level0 row13\" >13</th>\n",
       "      <td id=\"T_f3bc0_row13_col0\" class=\"data row13 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row13_col1\" class=\"data row13 col1\" >FAQ chunks</td>\n",
       "      <td id=\"T_f3bc0_row13_col2\" class=\"data row13 col2\" >507.000000</td>\n",
       "      <td id=\"T_f3bc0_row13_col3\" class=\"data row13 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row13_col4\" class=\"data row13 col4\" >Chunks generated from FAQ indexing records.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row14\" class=\"row_heading level0 row14\" >14</th>\n",
       "      <td id=\"T_f3bc0_row14_col0\" class=\"data row14 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row14_col1\" class=\"data row14 col1\" >Empty chunk_text</td>\n",
       "      <td id=\"T_f3bc0_row14_col2\" class=\"data row14 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row14_col3\" class=\"data row14 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row14_col4\" class=\"data row14 col4\" >Empty chunks should not exist.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row15\" class=\"row_heading level0 row15\" >15</th>\n",
       "      <td id=\"T_f3bc0_row15_col0\" class=\"data row15 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row15_col1\" class=\"data row15 col1\" >Missing parent_document_id</td>\n",
       "      <td id=\"T_f3bc0_row15_col2\" class=\"data row15 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row15_col3\" class=\"data row15 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row15_col4\" class=\"data row15 col4\" >Every chunk must link to a source record.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row16\" class=\"row_heading level0 row16\" >16</th>\n",
       "      <td id=\"T_f3bc0_row16_col0\" class=\"data row16 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row16_col1\" class=\"data row16 col1\" >Duplicated chunk_id</td>\n",
       "      <td id=\"T_f3bc0_row16_col2\" class=\"data row16 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row16_col3\" class=\"data row16 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row16_col4\" class=\"data row16 col4\" >Chunk IDs must be unique.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row17\" class=\"row_heading level0 row17\" >17</th>\n",
       "      <td id=\"T_f3bc0_row17_col0\" class=\"data row17 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row17_col1\" class=\"data row17 col1\" >Repealed legal chunks</td>\n",
       "      <td id=\"T_f3bc0_row17_col2\" class=\"data row17 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row17_col3\" class=\"data row17 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row17_col4\" class=\"data row17 col4\" >Must be zero to avoid retrieving repealed legal provisions.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row18\" class=\"row_heading level0 row18\" >18</th>\n",
       "      <td id=\"T_f3bc0_row18_col0\" class=\"data row18 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row18_col1\" class=\"data row18 col1\" >FAQ evaluation leakage in chunks</td>\n",
       "      <td id=\"T_f3bc0_row18_col2\" class=\"data row18 col2\" >0.000000</td>\n",
       "      <td id=\"T_f3bc0_row18_col3\" class=\"data row18 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row18_col4\" class=\"data row18 col4\" >Must be zero to avoid evaluation leakage.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row19\" class=\"row_heading level0 row19\" >19</th>\n",
       "      <td id=\"T_f3bc0_row19_col0\" class=\"data row19 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row19_col1\" class=\"data row19 col1\" >Mean words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row19_col2\" class=\"data row19 col2\" >83.020000</td>\n",
       "      <td id=\"T_f3bc0_row19_col3\" class=\"data row19 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row19_col4\" class=\"data row19 col4\" >Average retrieval granularity.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row20\" class=\"row_heading level0 row20\" >20</th>\n",
       "      <td id=\"T_f3bc0_row20_col0\" class=\"data row20 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row20_col1\" class=\"data row20 col1\" >Median words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row20_col2\" class=\"data row20 col2\" >68.000000</td>\n",
       "      <td id=\"T_f3bc0_row20_col3\" class=\"data row20 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row20_col4\" class=\"data row20 col4\" >Median retrieval granularity.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_f3bc0_level0_row21\" class=\"row_heading level0 row21\" >21</th>\n",
       "      <td id=\"T_f3bc0_row21_col0\" class=\"data row21 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_f3bc0_row21_col1\" class=\"data row21 col1\" >Max words per chunk</td>\n",
       "      <td id=\"T_f3bc0_row21_col2\" class=\"data row21 col2\" >500.000000</td>\n",
       "      <td id=\"T_f3bc0_row21_col3\" class=\"data row21 col3\" >OK</td>\n",
       "      <td id=\"T_f3bc0_row21_col4\" class=\"data row21 col4\" >Maximum chunk length should not exceed the configured limit: 500 words.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa20cbde50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_7dfbc th {\n",
       "  text-align: center;\n",
       "  font-weight: bold;\n",
       "  background-color: #f2f2f2;\n",
       "}\n",
       "#T_7dfbc caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "}\n",
       "#T_7dfbc_row0_col0, #T_7dfbc_row0_col1, #T_7dfbc_row0_col2, #T_7dfbc_row0_col3, #T_7dfbc_row0_col4, #T_7dfbc_row0_col5, #T_7dfbc_row1_col0, #T_7dfbc_row1_col1, #T_7dfbc_row1_col2, #T_7dfbc_row1_col3, #T_7dfbc_row1_col4, #T_7dfbc_row1_col5 {\n",
       "  text-align: center;\n",
       "  font-size: 12px;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_7dfbc\">\n",
       "  <caption>Chunk Length Summary by Strategy</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_7dfbc_level0_col0\" class=\"col_heading level0 col0\" >strategy</th>\n",
       "      <th id=\"T_7dfbc_level0_col1\" class=\"col_heading level0 col1\" >count</th>\n",
       "      <th id=\"T_7dfbc_level0_col2\" class=\"col_heading level0 col2\" >mean</th>\n",
       "      <th id=\"T_7dfbc_level0_col3\" class=\"col_heading level0 col3\" >median</th>\n",
       "      <th id=\"T_7dfbc_level0_col4\" class=\"col_heading level0 col4\" >min</th>\n",
       "      <th id=\"T_7dfbc_level0_col5\" class=\"col_heading level0 col5\" >max</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_7dfbc_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_7dfbc_row0_col0\" class=\"data row0 col0\" >Fixed-size Chunking Baseline</td>\n",
       "      <td id=\"T_7dfbc_row0_col1\" class=\"data row0 col1\" >719</td>\n",
       "      <td id=\"T_7dfbc_row0_col2\" class=\"data row0 col2\" >83.020000</td>\n",
       "      <td id=\"T_7dfbc_row0_col3\" class=\"data row0 col3\" >68.000000</td>\n",
       "      <td id=\"T_7dfbc_row0_col4\" class=\"data row0 col4\" >27</td>\n",
       "      <td id=\"T_7dfbc_row0_col5\" class=\"data row0 col5\" >500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_7dfbc_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_7dfbc_row1_col0\" class=\"data row1 col0\" >Structural Chunking</td>\n",
       "      <td id=\"T_7dfbc_row1_col1\" class=\"data row1 col1\" >722</td>\n",
       "      <td id=\"T_7dfbc_row1_col2\" class=\"data row1 col2\" >85.430000</td>\n",
       "      <td id=\"T_7dfbc_row1_col3\" class=\"data row1 col3\" >72.000000</td>\n",
       "      <td id=\"T_7dfbc_row1_col4\" class=\"data row1 col4\" >28</td>\n",
       "      <td id=\"T_7dfbc_row1_col5\" class=\"data row1 col5\" >653</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa20cbd950>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chunk quality reports saved successfully.\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\chunk_quality_report.csv\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\chunk_length_summary.csv\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 12 - Chunk Quality Checks\n",
    "# فحص جودة المقاطع ومقارنة استراتيجيات التقسيم\n",
    "# =========================================================\n",
    "\n",
    "chunk_quality_rows = []\n",
    "\n",
    "\n",
    "def add_chunk_check(strategy, name, value, status, interpretation=\"\"):\n",
    "    chunk_quality_rows.append({\n",
    "        \"strategy\": strategy,\n",
    "        \"check\": name,\n",
    "        \"value\": value,\n",
    "        \"status\": status,\n",
    "        \"interpretation\": interpretation,\n",
    "    })\n",
    "\n",
    "\n",
    "def add_chunk_lengths(df_chunks):\n",
    "    df = df_chunks.copy()\n",
    "\n",
    "    df[\"chunk_text\"] = df[\"chunk_text\"].fillna(\"\").astype(str)\n",
    "    df[\"chunk_char_len\"] = df[\"chunk_text\"].apply(clean_basic_text).str.len()\n",
    "    df[\"chunk_word_len\"] = df[\"chunk_text\"].apply(clean_basic_text).str.split().apply(len)\n",
    "\n",
    "    return df\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Add length statistics\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "df_structural_chunks = add_chunk_lengths(df_structural_chunks)\n",
    "df_fixed_chunks = add_chunk_lengths(df_fixed_chunks)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Quality checks for each chunking strategy\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "for strategy_name, df_chunks, max_allowed_words in [\n",
    "    (\"Structural Chunking\", df_structural_chunks, STRUCTURAL_MAX_WORDS),\n",
    "    (\"Fixed-size Chunking Baseline\", df_fixed_chunks, CHUNK_SIZE_WORDS),\n",
    "]:\n",
    "    empty_chunks = int((df_chunks[\"chunk_text\"].apply(clean_basic_text).str.len() == 0).sum())\n",
    "    missing_parent = int((df_chunks[\"parent_document_id\"].apply(clean_basic_text).str.len() == 0).sum())\n",
    "    duplicated_chunk_ids = int(df_chunks[\"chunk_id\"].duplicated().sum())\n",
    "\n",
    "    max_words = int(df_chunks[\"chunk_word_len\"].max()) if len(df_chunks) else 0\n",
    "    mean_words = round(float(df_chunks[\"chunk_word_len\"].mean()), 2) if len(df_chunks) else 0\n",
    "    median_words = round(float(df_chunks[\"chunk_word_len\"].median()), 2) if len(df_chunks) else 0\n",
    "\n",
    "    legal_chunks = int((df_chunks[\"source_type\"] == \"legal_article\").sum())\n",
    "    faq_chunks = int((df_chunks[\"source_type\"] == \"faq\").sum())\n",
    "\n",
    "    # المواد الملغاة مستبعدة مسبقاً من قاعدة المعرفة (Stage 04.1 و Stage 08)\n",
    "    # لذلك نفحص العمود فقط إن وُجد، وإلا نعتبر العدد صفراً\n",
    "    if \"article_status\" in df_chunks.columns:\n",
    "        repealed_chunks = int(\n",
    "            (\n",
    "                (df_chunks[\"source_type\"] == \"legal_article\") &\n",
    "                (df_chunks[\"article_status\"] == \"repealed\")\n",
    "            ).sum()\n",
    "        )\n",
    "        repealed_interpretation = \"Must be zero to avoid retrieving repealed legal provisions.\"\n",
    "    else:\n",
    "        repealed_chunks = 0\n",
    "        repealed_interpretation = (\n",
    "            \"Repealed articles are excluded at the source (Stage 04.1 and Stage 08); \"\n",
    "            \"this check is precautionary.\"\n",
    "        )\n",
    "\n",
    "    faq_eval_leakage = len(\n",
    "        set(\n",
    "            df_chunks[\n",
    "                df_chunks[\"source_type\"] == \"faq\"\n",
    "            ][\"parent_document_id\"]\n",
    "        )\n",
    "        &\n",
    "        set(df_faq_evaluation[\"document_unit_id\"])\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Total chunks\",\n",
    "        len(df_chunks),\n",
    "        \"OK\" if len(df_chunks) > 0 else \"FAIL\",\n",
    "        \"Total number of generated chunks.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Legal article chunks\",\n",
    "        legal_chunks,\n",
    "        \"OK\" if legal_chunks > 0 else \"WARN\",\n",
    "        \"Chunks generated from active legal articles.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"FAQ chunks\",\n",
    "        faq_chunks,\n",
    "        \"OK\" if faq_chunks > 0 else \"WARN\",\n",
    "        \"Chunks generated from FAQ indexing records.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Empty chunk_text\",\n",
    "        empty_chunks,\n",
    "        \"OK\" if empty_chunks == 0 else \"FAIL\",\n",
    "        \"Empty chunks should not exist.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Missing parent_document_id\",\n",
    "        missing_parent,\n",
    "        \"OK\" if missing_parent == 0 else \"FAIL\",\n",
    "        \"Every chunk must link to a source record.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Duplicated chunk_id\",\n",
    "        duplicated_chunk_ids,\n",
    "        \"OK\" if duplicated_chunk_ids == 0 else \"FAIL\",\n",
    "        \"Chunk IDs must be unique.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Repealed legal chunks\",\n",
    "        repealed_chunks,\n",
    "        \"OK\" if repealed_chunks == 0 else \"FAIL\",\n",
    "        repealed_interpretation\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"FAQ evaluation leakage in chunks\",\n",
    "        faq_eval_leakage,\n",
    "        \"OK\" if faq_eval_leakage == 0 else \"FAIL\",\n",
    "        \"Must be zero to avoid evaluation leakage.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Mean words per chunk\",\n",
    "        mean_words,\n",
    "        \"OK\",\n",
    "        \"Average retrieval granularity.\"\n",
    "    )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Median words per chunk\",\n",
    "        median_words,\n",
    "        \"OK\",\n",
    "        \"Median retrieval granularity.\"\n",
    "    )\n",
    "\n",
    "    # ملاحظة: التقسيم الهيكلي يُبقي المادة الطويلة كوحدة واحدة،\n",
    "    # لذلك قد يتجاوز طولها الحد المرجعي، وهذا سلوك مقصود وليس خطأ\n",
    "    if strategy_name.startswith(\"Structural\"):\n",
    "        max_status = \"OK\"\n",
    "        max_interpretation = (\n",
    "            \"Structural chunking keeps each article intact; \"\n",
    "            f\"exceeding {max_allowed_words} words is expected for long articles.\"\n",
    "        )\n",
    "    else:\n",
    "        max_status = \"OK\" if max_words <= max_allowed_words else \"WARN\"\n",
    "        max_interpretation = (\n",
    "            f\"Maximum chunk length should not exceed the configured limit: {max_allowed_words} words.\"\n",
    "        )\n",
    "\n",
    "    add_chunk_check(\n",
    "        strategy_name,\n",
    "        \"Max words per chunk\",\n",
    "        max_words,\n",
    "        max_status,\n",
    "        max_interpretation\n",
    "    )\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Build quality report\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "chunk_quality_report = pd.DataFrame(chunk_quality_rows)\n",
    "\n",
    "display(\n",
    "    chunk_quality_report\n",
    "    .style\n",
    "    .set_caption(\"Chunk Quality Report\")\n",
    "    .set_properties(**{\n",
    "        \"text-align\": \"left\",\n",
    "        \"white-space\": \"normal\",\n",
    "        \"font-size\": \"12px\"\n",
    "    })\n",
    "    .set_table_styles([\n",
    "        {\n",
    "            \"selector\": \"th\",\n",
    "            \"props\": [\n",
    "                (\"text-align\", \"center\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"background-color\", \"#f2f2f2\")\n",
    "            ]\n",
    "        },\n",
    "        {\n",
    "            \"selector\": \"caption\",\n",
    "            \"props\": [\n",
    "                (\"caption-side\", \"top\"),\n",
    "                (\"font-size\", \"16px\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"text-align\", \"left\")\n",
    "            ]\n",
    "        }\n",
    "    ])\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Chunk length summary\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "chunk_length_summary = (\n",
    "    pd.concat([\n",
    "        df_structural_chunks.assign(strategy=\"Structural Chunking\"),\n",
    "        df_fixed_chunks.assign(strategy=\"Fixed-size Chunking Baseline\"),\n",
    "    ], ignore_index=True)\n",
    "    .groupby(\"strategy\")[\"chunk_word_len\"]\n",
    "    .agg(\n",
    "        count=\"count\",\n",
    "        mean=\"mean\",\n",
    "        median=\"median\",\n",
    "        min=\"min\",\n",
    "        max=\"max\"\n",
    "    )\n",
    "    .round(2)\n",
    "    .reset_index()\n",
    ")\n",
    "\n",
    "display(\n",
    "    chunk_length_summary\n",
    "    .style\n",
    "    .set_caption(\"Chunk Length Summary by Strategy\")\n",
    "    .set_properties(**{\n",
    "        \"text-align\": \"center\",\n",
    "        \"font-size\": \"12px\"\n",
    "    })\n",
    "    .set_table_styles([\n",
    "        {\n",
    "            \"selector\": \"th\",\n",
    "            \"props\": [\n",
    "                (\"text-align\", \"center\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"background-color\", \"#f2f2f2\")\n",
    "            ]\n",
    "        },\n",
    "        {\n",
    "            \"selector\": \"caption\",\n",
    "            \"props\": [\n",
    "                (\"caption-side\", \"top\"),\n",
    "                (\"font-size\", \"16px\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"text-align\", \"left\")\n",
    "            ]\n",
    "        }\n",
    "    ])\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Safety assertions\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "failed_checks = chunk_quality_report[chunk_quality_report[\"status\"] == \"FAIL\"]\n",
    "\n",
    "assert failed_checks.empty, (\n",
    "    \"Chunk quality checks failed. Review the following checks:\\n\"\n",
    "    + failed_checks.to_string(index=False)\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Save reports\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "chunk_quality_report.to_csv(\n",
    "    REPORTS_DIR / \"chunk_quality_report.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "chunk_quality_report.to_excel(\n",
    "    REPORTS_DIR / \"chunk_quality_report.xlsx\",\n",
    "    index=False\n",
    ")\n",
    "\n",
    "chunk_length_summary.to_csv(\n",
    "    REPORTS_DIR / \"chunk_length_summary.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "chunk_length_summary.to_excel(\n",
    "    REPORTS_DIR / \"chunk_length_summary.xlsx\",\n",
    "    index=False\n",
    ")\n",
    "\n",
    "print(\"Chunk quality reports saved successfully.\")\n",
    "print(REPORTS_DIR / \"chunk_quality_report.csv\")\n",
    "print(REPORTS_DIR / \"chunk_length_summary.csv\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "376c6024-b4bd-447c-8e21-12e5fc4a3c0d",
   "metadata": {},
   "source": [
    "### Interpretation — Chunk Quality Report\n",
    "\n",
    "يوضح تقرير جودة التقسيم أن عمليتي التقسيم، سواء **Structural Chunking** أو **Fixed-size Chunking Baseline**، تم تنفيذهما بنجاح وبدون مشاكل جوهرية في جودة البيانات. فقد أظهرت النتائج عدم وجود مقاطع فارغة، وعدم وجود معرفات مكررة للمقاطع، كما أن جميع المقاطع مرتبطة بسجلاتها الأصلية من خلال `parent_document_id`.\n",
    "\n",
    "من ناحية السلامة القانونية، تؤكد النتائج أن عدد المقاطع الناتجة من المواد القانونية الملغاة يساوي صفرًا في كلتا الطريقتين. وهذا يعد مؤشرًا مهمًا في هذا المشروع، لأن إدخال مواد ملغاة داخل قاعدة الاسترجاع قد يؤدي إلى توليد إجابات قانونية غير صحيحة أو غير محدثة.\n",
    "\n",
    "كما أظهرت النتائج عدم وجود أي تسريب من أسئلة FAQ المخصصة للتقييم داخل المقاطع المستخدمة في الفهرسة. وهذا يؤكد أن مجموعة التقييم بقيت منفصلة عن قاعدة المعرفة التجريبية، مما يجعل نتائج تقييم الاسترجاع أكثر عدالة وموثوقية.\n",
    "\n",
    "عند مقارنة الطريقتين، أنتجت طريقة **Structural Chunking** عددًا قريبًا من طريقة **Fixed-size Chunking**، حيث تم إنتاج 722 مقطعًا بالطريقة الهيكلية مقابل 719 مقطعًا بالطريقة الثابتة. كما أن متوسط طول المقاطع متقارب بين الطريقتين، حيث بلغ متوسط الطول 85.43 كلمة في التقسيم الهيكلي و83.02 كلمة في التقسيم الثابت.\n",
    "\n",
    "الفرق الأساسي بين الطريقتين يظهر في الحد الأقصى لطول المقطع. ففي طريقة **Fixed-size Chunking** بلغ الحد الأقصى 500 كلمة، وهو متوافق مع إعدادات التقسيم الثابت. أما في طريقة **Structural Chunking** فقد وصل الحد الأقصى إلى 653 كلمة، وهذا متوقع لأن هذه الطريقة تحافظ على النص القانوني كوحدة متماسكة قدر الإمكان بدلًا من قطع المادة القانونية الطويلة بشكل عشوائي.\n",
    "\n",
    "بناءً على ذلك، تشير النتائج إلى أن كلتا الطريقتين صالحتان من ناحية الجودة والسلامة، لكن الفرق بينهما سيتم الحكم عليه بشكل أدق في مرحلة تقييم الاسترجاع، من خلال مقارنة قدرة كل طريقة على استرجاع المادة القانونية أو الإجابة الصحيحة باستخدام مقاييس مثل Recall@k وMRR وArticle Hit Rate.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fdc356d",
   "metadata": {},
   "source": [
    "## Stage 13 — Academic Dataset Summary and Visualisation\n",
    "\n",
    "This stage produces the final academic summary of the prepared dataset and generates visualisations for reporting.\n",
    "\n",
    "The purpose of these outputs is not only descriptive. They support the research methodology by showing:\n",
    "\n",
    "1. The difference between legal audit completeness and RAG retrieval safety.\n",
    "2. The effect of cleaning and filtering on the dataset size.\n",
    "3. The absence of FAQ leakage between indexing and evaluation.\n",
    "4. The distribution of text lengths and metadata categories.\n",
    "5. The comparison between structural and fixed-size chunking strategies.\n",
    "\n",
    "These summaries and figures can be used later in the methodology and results sections of the project report.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "17ec139a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style type=\"text/css\">\n",
       "#T_34554 th {\n",
       "  text-align: center;\n",
       "  font-weight: bold;\n",
       "  background-color: #f2f2f2;\n",
       "}\n",
       "#T_34554 caption {\n",
       "  caption-side: top;\n",
       "  font-size: 16px;\n",
       "  font-weight: bold;\n",
       "  text-align: left;\n",
       "}\n",
       "#T_34554_row0_col0, #T_34554_row0_col1, #T_34554_row0_col2, #T_34554_row0_col3, #T_34554_row0_col4, #T_34554_row1_col0, #T_34554_row1_col1, #T_34554_row1_col2, #T_34554_row1_col3, #T_34554_row1_col4, #T_34554_row2_col0, #T_34554_row2_col1, #T_34554_row2_col2, #T_34554_row2_col3, #T_34554_row2_col4, #T_34554_row3_col0, #T_34554_row3_col1, #T_34554_row3_col2, #T_34554_row3_col3, #T_34554_row3_col4, #T_34554_row4_col0, #T_34554_row4_col1, #T_34554_row4_col2, #T_34554_row4_col3, #T_34554_row4_col4, #T_34554_row5_col0, #T_34554_row5_col1, #T_34554_row5_col2, #T_34554_row5_col3, #T_34554_row5_col4, #T_34554_row6_col0, #T_34554_row6_col1, #T_34554_row6_col2, #T_34554_row6_col3, #T_34554_row6_col4, #T_34554_row7_col0, #T_34554_row7_col1, #T_34554_row7_col2, #T_34554_row7_col3, #T_34554_row7_col4, #T_34554_row8_col0, #T_34554_row8_col1, #T_34554_row8_col2, #T_34554_row8_col3, #T_34554_row8_col4, #T_34554_row9_col0, #T_34554_row9_col1, #T_34554_row9_col2, #T_34554_row9_col3, #T_34554_row9_col4, #T_34554_row10_col0, #T_34554_row10_col1, #T_34554_row10_col2, #T_34554_row10_col3, #T_34554_row10_col4, #T_34554_row11_col0, #T_34554_row11_col1, #T_34554_row11_col2, #T_34554_row11_col3, #T_34554_row11_col4, #T_34554_row12_col0, #T_34554_row12_col1, #T_34554_row12_col2, #T_34554_row12_col3, #T_34554_row12_col4, #T_34554_row13_col0, #T_34554_row13_col1, #T_34554_row13_col2, #T_34554_row13_col3, #T_34554_row13_col4, #T_34554_row14_col0, #T_34554_row14_col1, #T_34554_row14_col2, #T_34554_row14_col3, #T_34554_row14_col4, #T_34554_row15_col0, #T_34554_row15_col1, #T_34554_row15_col2, #T_34554_row15_col3, #T_34554_row15_col4, #T_34554_row16_col0, #T_34554_row16_col1, #T_34554_row16_col2, #T_34554_row16_col3, #T_34554_row16_col4, #T_34554_row17_col0, #T_34554_row17_col1, #T_34554_row17_col2, #T_34554_row17_col3, #T_34554_row17_col4, #T_34554_row18_col0, #T_34554_row18_col1, #T_34554_row18_col2, #T_34554_row18_col3, #T_34554_row18_col4, #T_34554_row19_col0, #T_34554_row19_col1, #T_34554_row19_col2, #T_34554_row19_col3, #T_34554_row19_col4, #T_34554_row20_col0, #T_34554_row20_col1, #T_34554_row20_col2, #T_34554_row20_col3, #T_34554_row20_col4, #T_34554_row21_col0, #T_34554_row21_col1, #T_34554_row21_col2, #T_34554_row21_col3, #T_34554_row21_col4, #T_34554_row22_col0, #T_34554_row22_col1, #T_34554_row22_col2, #T_34554_row22_col3, #T_34554_row22_col4, #T_34554_row23_col0, #T_34554_row23_col1, #T_34554_row23_col2, #T_34554_row23_col3, #T_34554_row23_col4 {\n",
       "  text-align: left;\n",
       "  white-space: normal;\n",
       "  font-size: 12px;\n",
       "}\n",
       "</style>\n",
       "<table id=\"T_34554\">\n",
       "  <caption>Academic Dataset Summary</caption>\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th class=\"blank level0\" >&nbsp;</th>\n",
       "      <th id=\"T_34554_level0_col0\" class=\"col_heading level0 col0\" >category</th>\n",
       "      <th id=\"T_34554_level0_col1\" class=\"col_heading level0 col1\" >metric</th>\n",
       "      <th id=\"T_34554_level0_col2\" class=\"col_heading level0 col2\" >value</th>\n",
       "      <th id=\"T_34554_level0_col3\" class=\"col_heading level0 col3\" >status</th>\n",
       "      <th id=\"T_34554_level0_col4\" class=\"col_heading level0 col4\" >interpretation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row0\" class=\"row_heading level0 row0\" >0</th>\n",
       "      <td id=\"T_34554_row0_col0\" class=\"data row0 col0\" >Legal Dataset</td>\n",
       "      <td id=\"T_34554_row0_col1\" class=\"data row0 col1\" >Clean legal article records - audit dataset</td>\n",
       "      <td id=\"T_34554_row0_col2\" class=\"data row0 col2\" >249</td>\n",
       "      <td id=\"T_34554_row0_col3\" class=\"data row0 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row0_col4\" class=\"data row0 col4\" >All cleaned legal records are retained for auditability, including legal variants such as repeated articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row1\" class=\"row_heading level0 row1\" >1</th>\n",
       "      <td id=\"T_34554_row1_col0\" class=\"data row1 col0\" >Legal Dataset</td>\n",
       "      <td id=\"T_34554_row1_col1\" class=\"data row1 col1\" >Unique numeric legal articles</td>\n",
       "      <td id=\"T_34554_row1_col2\" class=\"data row1 col2\" >245</td>\n",
       "      <td id=\"T_34554_row1_col3\" class=\"data row1 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row1_col4\" class=\"data row1 col4\" >Represents the official numeric sequence of Saudi Labor Law articles.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row2\" class=\"row_heading level0 row2\" >2</th>\n",
       "      <td id=\"T_34554_row2_col0\" class=\"data row2 col0\" >Legal Dataset</td>\n",
       "      <td id=\"T_34554_row2_col1\" class=\"data row2 col1\" >Legal repeated numeric labels kept as variants</td>\n",
       "      <td id=\"T_34554_row2_col2\" class=\"data row2 col2\" >4</td>\n",
       "      <td id=\"T_34554_row2_col3\" class=\"data row2 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row2_col4\" class=\"data row2 col4\" >Repeated numeric labels are preserved because legal labels such as 'مكرر' represent valid legal variants, not duplicate rows.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row3\" class=\"row_heading level0 row3\" >3</th>\n",
       "      <td id=\"T_34554_row3_col0\" class=\"data row3 col0\" >Legal Dataset</td>\n",
       "      <td id=\"T_34554_row3_col1\" class=\"data row3 col1\" >Active legal articles allowed for RAG</td>\n",
       "      <td id=\"T_34554_row3_col2\" class=\"data row3 col2\" >211</td>\n",
       "      <td id=\"T_34554_row3_col3\" class=\"data row3 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row3_col4\" class=\"data row3 col4\" >Only active legal articles are allowed inside the RAG indexing knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row4\" class=\"row_heading level0 row4\" >4</th>\n",
       "      <td id=\"T_34554_row4_col0\" class=\"data row4 col0\" >Legal Dataset</td>\n",
       "      <td id=\"T_34554_row4_col1\" class=\"data row4 col1\" >Repealed legal articles archived only</td>\n",
       "      <td id=\"T_34554_row4_col2\" class=\"data row4 col2\" >38</td>\n",
       "      <td id=\"T_34554_row4_col3\" class=\"data row4 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row4_col4\" class=\"data row4 col4\" >Repealed legal articles are retained for transparency but excluded from retrieval indexing.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row5\" class=\"row_heading level0 row5\" >5</th>\n",
       "      <td id=\"T_34554_row5_col0\" class=\"data row5 col0\" >RAG Safety</td>\n",
       "      <td id=\"T_34554_row5_col1\" class=\"data row5 col1\" >Repealed articles inside experimental KB</td>\n",
       "      <td id=\"T_34554_row5_col2\" class=\"data row5 col2\" >0</td>\n",
       "      <td id=\"T_34554_row5_col3\" class=\"data row5 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row5_col4\" class=\"data row5 col4\" >Must be zero to prevent retrieval from repealed legal provisions.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row6\" class=\"row_heading level0 row6\" >6</th>\n",
       "      <td id=\"T_34554_row6_col0\" class=\"data row6 col0\" >FAQ Dataset</td>\n",
       "      <td id=\"T_34554_row6_col1\" class=\"data row6 col1\" >Clean FAQ records</td>\n",
       "      <td id=\"T_34554_row6_col2\" class=\"data row6 col2\" >703</td>\n",
       "      <td id=\"T_34554_row6_col3\" class=\"data row6 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row6_col4\" class=\"data row6 col4\" >FAQ records after cleaning and duplicate removal.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row7\" class=\"row_heading level0 row7\" >7</th>\n",
       "      <td id=\"T_34554_row7_col0\" class=\"data row7 col0\" >FAQ Dataset</td>\n",
       "      <td id=\"T_34554_row7_col1\" class=\"data row7 col1\" >FAQ indexing records</td>\n",
       "      <td id=\"T_34554_row7_col2\" class=\"data row7 col2\" >503</td>\n",
       "      <td id=\"T_34554_row7_col3\" class=\"data row7 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row7_col4\" class=\"data row7 col4\" >FAQ records included in the experimental knowledge base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row8\" class=\"row_heading level0 row8\" >8</th>\n",
       "      <td id=\"T_34554_row8_col0\" class=\"data row8 col0\" >FAQ Dataset</td>\n",
       "      <td id=\"T_34554_row8_col1\" class=\"data row8 col1\" >FAQ evaluation records held out</td>\n",
       "      <td id=\"T_34554_row8_col2\" class=\"data row8 col2\" >200</td>\n",
       "      <td id=\"T_34554_row8_col3\" class=\"data row8 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row8_col4\" class=\"data row8 col4\" >FAQ records reserved for evaluation and excluded from the experimental KB.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row9\" class=\"row_heading level0 row9\" >9</th>\n",
       "      <td id=\"T_34554_row9_col0\" class=\"data row9 col0\" >Evaluation Safety</td>\n",
       "      <td id=\"T_34554_row9_col1\" class=\"data row9 col1\" >FAQ leakage between indexing and evaluation</td>\n",
       "      <td id=\"T_34554_row9_col2\" class=\"data row9 col2\" >0</td>\n",
       "      <td id=\"T_34554_row9_col3\" class=\"data row9 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row9_col4\" class=\"data row9 col4\" >Must be zero to avoid inflated retrieval scores.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row10\" class=\"row_heading level0 row10\" >10</th>\n",
       "      <td id=\"T_34554_row10_col0\" class=\"data row10 col0\" >Evaluation Safety</td>\n",
       "      <td id=\"T_34554_row10_col1\" class=\"data row10 col1\" >FAQ evaluation records leaked into experimental KB</td>\n",
       "      <td id=\"T_34554_row10_col2\" class=\"data row10 col2\" >0</td>\n",
       "      <td id=\"T_34554_row10_col3\" class=\"data row10 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row10_col4\" class=\"data row10 col4\" >Must be zero because evaluation questions should not appear in the experimental retrieval base.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row11\" class=\"row_heading level0 row11\" >11</th>\n",
       "      <td id=\"T_34554_row11_col0\" class=\"data row11 col0\" >Knowledge Base</td>\n",
       "      <td id=\"T_34554_row11_col1\" class=\"data row11 col1\" >Experimental KB records</td>\n",
       "      <td id=\"T_34554_row11_col2\" class=\"data row11 col2\" >714</td>\n",
       "      <td id=\"T_34554_row11_col3\" class=\"data row11 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row11_col4\" class=\"data row11 col4\" >Experimental KB contains active legal articles and FAQ indexing records only.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row12\" class=\"row_heading level0 row12\" >12</th>\n",
       "      <td id=\"T_34554_row12_col0\" class=\"data row12 col0\" >Knowledge Base</td>\n",
       "      <td id=\"T_34554_row12_col1\" class=\"data row12 col1\" >Full production KB records</td>\n",
       "      <td id=\"T_34554_row12_col2\" class=\"data row12 col2\" >914</td>\n",
       "      <td id=\"T_34554_row12_col3\" class=\"data row12 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row12_col4\" class=\"data row12 col4\" >Production KB contains active legal articles and all clean FAQ records after evaluation.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row13\" class=\"row_heading level0 row13\" >13</th>\n",
       "      <td id=\"T_34554_row13_col0\" class=\"data row13 col0\" >Chunking</td>\n",
       "      <td id=\"T_34554_row13_col1\" class=\"data row13 col1\" >Structural chunks</td>\n",
       "      <td id=\"T_34554_row13_col2\" class=\"data row13 col2\" >722</td>\n",
       "      <td id=\"T_34554_row13_col3\" class=\"data row13 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row13_col4\" class=\"data row13 col4\" >Chunks generated using the safe structural chunking strategy.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row14\" class=\"row_heading level0 row14\" >14</th>\n",
       "      <td id=\"T_34554_row14_col0\" class=\"data row14 col0\" >Chunking</td>\n",
       "      <td id=\"T_34554_row14_col1\" class=\"data row14 col1\" >Fixed-size chunks</td>\n",
       "      <td id=\"T_34554_row14_col2\" class=\"data row14 col2\" >719</td>\n",
       "      <td id=\"T_34554_row14_col3\" class=\"data row14 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row14_col4\" class=\"data row14 col4\" >Chunks generated using the fixed-size baseline strategy.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row15\" class=\"row_heading level0 row15\" >15</th>\n",
       "      <td id=\"T_34554_row15_col0\" class=\"data row15 col0\" >Chunking Safety</td>\n",
       "      <td id=\"T_34554_row15_col1\" class=\"data row15 col1\" >Repealed legal chunks - structural</td>\n",
       "      <td id=\"T_34554_row15_col2\" class=\"data row15 col2\" >0</td>\n",
       "      <td id=\"T_34554_row15_col3\" class=\"data row15 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row15_col4\" class=\"data row15 col4\" >Must be zero to ensure repealed legal articles were not chunked for retrieval.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row16\" class=\"row_heading level0 row16\" >16</th>\n",
       "      <td id=\"T_34554_row16_col0\" class=\"data row16 col0\" >Chunking Safety</td>\n",
       "      <td id=\"T_34554_row16_col1\" class=\"data row16 col1\" >Repealed legal chunks - fixed-size</td>\n",
       "      <td id=\"T_34554_row16_col2\" class=\"data row16 col2\" >0</td>\n",
       "      <td id=\"T_34554_row16_col3\" class=\"data row16 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row16_col4\" class=\"data row16 col4\" >Must be zero to ensure repealed legal articles were not chunked in the baseline.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row17\" class=\"row_heading level0 row17\" >17</th>\n",
       "      <td id=\"T_34554_row17_col0\" class=\"data row17 col0\" >Evaluation Dataset</td>\n",
       "      <td id=\"T_34554_row17_col1\" class=\"data row17 col1\" >Total evaluation questions</td>\n",
       "      <td id=\"T_34554_row17_col2\" class=\"data row17 col2\" >238</td>\n",
       "      <td id=\"T_34554_row17_col3\" class=\"data row17 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row17_col4\" class=\"data row17 col4\" >Unified evaluation dataset including FAQ, legal article questions, and out-of-scope tests.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row18\" class=\"row_heading level0 row18\" >18</th>\n",
       "      <td id=\"T_34554_row18_col0\" class=\"data row18 col0\" >Evaluation Dataset</td>\n",
       "      <td id=\"T_34554_row18_col1\" class=\"data row18 col1\" >FAQ evaluation questions</td>\n",
       "      <td id=\"T_34554_row18_col2\" class=\"data row18 col2\" >199</td>\n",
       "      <td id=\"T_34554_row18_col3\" class=\"data row18 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row18_col4\" class=\"data row18 col4\" >Held-out FAQ questions used for retrieval evaluation.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row19\" class=\"row_heading level0 row19\" >19</th>\n",
       "      <td id=\"T_34554_row19_col0\" class=\"data row19 col0\" >Evaluation Dataset</td>\n",
       "      <td id=\"T_34554_row19_col1\" class=\"data row19 col1\" >Legal article evaluation questions</td>\n",
       "      <td id=\"T_34554_row19_col2\" class=\"data row19 col2\" >24</td>\n",
       "      <td id=\"T_34554_row19_col3\" class=\"data row19 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row19_col4\" class=\"data row19 col4\" >Manual legal questions linked to gold legal article references.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row20\" class=\"row_heading level0 row20\" >20</th>\n",
       "      <td id=\"T_34554_row20_col0\" class=\"data row20 col0\" >Evaluation Dataset</td>\n",
       "      <td id=\"T_34554_row20_col1\" class=\"data row20 col1\" >Out-of-scope evaluation questions</td>\n",
       "      <td id=\"T_34554_row20_col2\" class=\"data row20 col2\" >15</td>\n",
       "      <td id=\"T_34554_row20_col3\" class=\"data row20 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row20_col4\" class=\"data row20 col4\" >Questions used to test refusal behavior outside Saudi Labor Law.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row21\" class=\"row_heading level0 row21\" >21</th>\n",
       "      <td id=\"T_34554_row21_col0\" class=\"data row21 col0\" >Metadata Coverage</td>\n",
       "      <td id=\"T_34554_row21_col1\" class=\"data row21 col1\" >Unique legal chapters</td>\n",
       "      <td id=\"T_34554_row21_col2\" class=\"data row21 col2\" >16</td>\n",
       "      <td id=\"T_34554_row21_col3\" class=\"data row21 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row21_col4\" class=\"data row21 col4\" >Number of unique legal chapters represented in the cleaned legal dataset.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row22\" class=\"row_heading level0 row22\" >22</th>\n",
       "      <td id=\"T_34554_row22_col0\" class=\"data row22 col0\" >Metadata Coverage</td>\n",
       "      <td id=\"T_34554_row22_col1\" class=\"data row22 col1\" >Unique FAQ sectors</td>\n",
       "      <td id=\"T_34554_row22_col2\" class=\"data row22 col2\" >5</td>\n",
       "      <td id=\"T_34554_row22_col3\" class=\"data row22 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row22_col4\" class=\"data row22 col4\" >Number of unique FAQ sectors represented after cleaning.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th id=\"T_34554_level0_row23\" class=\"row_heading level0 row23\" >23</th>\n",
       "      <td id=\"T_34554_row23_col0\" class=\"data row23 col0\" >Metadata Coverage</td>\n",
       "      <td id=\"T_34554_row23_col1\" class=\"data row23 col1\" >Unique FAQ subsites</td>\n",
       "      <td id=\"T_34554_row23_col2\" class=\"data row23 col2\" >1</td>\n",
       "      <td id=\"T_34554_row23_col3\" class=\"data row23 col3\" >OK</td>\n",
       "      <td id=\"T_34554_row23_col4\" class=\"data row23 col4\" >Number of unique FAQ subsites represented after cleaning.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n"
      ],
      "text/plain": [
       "<pandas.io.formats.style.Styler at 0x1fa20b9b890>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Academic dataset summary saved successfully.\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.csv\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.xlsx\n",
      "saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.json\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 13 - Academic Dataset Summary\n",
    "# ملخص أكاديمي نهائي لمخرجات مرحلة إعداد البيانات\n",
    "# =========================================================\n",
    "\n",
    "REPORTS_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Add text length features where applicable\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "for df_tmp in [\n",
    "    df_articles,\n",
    "    df_articles_active,\n",
    "    df_articles_repealed,\n",
    "    df_faq,\n",
    "    df_kb_experiment,\n",
    "    df_kb_full_production,\n",
    "    df_eval\n",
    "]:\n",
    "    if isinstance(df_tmp, pd.DataFrame) and \"text_for_indexing\" in df_tmp.columns:\n",
    "        df_tmp[\"indexing_char_len\"] = df_tmp[\"text_for_indexing\"].fillna(\"\").astype(str).str.len()\n",
    "        df_tmp[\"indexing_word_len\"] = df_tmp[\"text_for_indexing\"].fillna(\"\").astype(str).str.split().apply(len)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Core metrics\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "legal_numeric_count = int(df_articles[\"article_number_int\"].dropna().astype(int).nunique())\n",
    "legal_record_count = int(len(df_articles))\n",
    "legal_repeated_numeric_count = int(df_articles[\"article_number_int\"].duplicated().sum())\n",
    "\n",
    "legal_active_count = int(len(df_articles_active))\n",
    "legal_repealed_count = int(len(df_articles_repealed))\n",
    "\n",
    "repealed_in_experiment_kb = int(\n",
    "    (\n",
    "        (df_kb_experiment[\"source_type\"] == \"legal_article\") &\n",
    "        (df_kb_experiment[\"article_status\"] == \"repealed\")\n",
    "    ).sum()\n",
    ")\n",
    "\n",
    "faq_leakage_count = int(\n",
    "    len(\n",
    "        set(df_faq_indexing[\"document_unit_id\"]) &\n",
    "        set(df_faq_evaluation[\"document_unit_id\"])\n",
    "    )\n",
    ")\n",
    "\n",
    "faq_eval_leakage_in_kb = int(\n",
    "    len(\n",
    "        set(df_kb_experiment[df_kb_experiment[\"source_type\"] == \"faq\"][\"document_unit_id\"]) &\n",
    "        set(df_faq_evaluation[\"document_unit_id\"])\n",
    "    )\n",
    ")\n",
    "\n",
    "\n",
    "def count_repealed_legal_chunks(df_chunks):\n",
    "    \"\"\"\n",
    "    المواد الملغاة مستبعدة مسبقاً من قاعدة المعرفة (Stage 04.1 و Stage 08).\n",
    "    لذلك نفحص عمود الحالة فقط إن وُجد، وإلا نعتبر العدد صفراً.\n",
    "    \"\"\"\n",
    "    if \"article_status\" not in df_chunks.columns:\n",
    "        return 0\n",
    "    return int(\n",
    "        (\n",
    "            (df_chunks[\"source_type\"] == \"legal_article\") &\n",
    "            (df_chunks[\"article_status\"] == \"repealed\")\n",
    "        ).sum()\n",
    "    )\n",
    "\n",
    "\n",
    "structural_repealed_chunks = count_repealed_legal_chunks(df_structural_chunks)\n",
    "fixed_repealed_chunks = count_repealed_legal_chunks(df_fixed_chunks)\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Build academic summary rows\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "summary_rows = []\n",
    "\n",
    "def add_summary(category, metric, value, status, interpretation):\n",
    "    summary_rows.append({\n",
    "        \"category\": category,\n",
    "        \"metric\": metric,\n",
    "        \"value\": value,\n",
    "        \"status\": status,\n",
    "        \"interpretation\": interpretation\n",
    "    })\n",
    "\n",
    "\n",
    "# Legal dataset\n",
    "add_summary(\n",
    "    \"Legal Dataset\",\n",
    "    \"Clean legal article records - audit dataset\",\n",
    "    legal_record_count,\n",
    "    \"OK\" if legal_record_count > 0 else \"FAIL\",\n",
    "    \"All cleaned legal records are retained for auditability, including legal variants such as repeated articles.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Legal Dataset\",\n",
    "    \"Unique numeric legal articles\",\n",
    "    legal_numeric_count,\n",
    "    \"OK\" if legal_numeric_count == 245 else \"WARN\",\n",
    "    \"Represents the official numeric sequence of Saudi Labor Law articles.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Legal Dataset\",\n",
    "    \"Legal repeated numeric labels kept as variants\",\n",
    "    legal_repeated_numeric_count,\n",
    "    \"OK\",\n",
    "    \"Repeated numeric labels are preserved because legal labels such as 'مكرر' represent valid legal variants, not duplicate rows.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Legal Dataset\",\n",
    "    \"Active legal articles allowed for RAG\",\n",
    "    legal_active_count,\n",
    "    \"OK\" if legal_active_count > 0 else \"FAIL\",\n",
    "    \"Only active legal articles are allowed inside the RAG indexing knowledge base.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Legal Dataset\",\n",
    "    \"Repealed legal articles archived only\",\n",
    "    legal_repealed_count,\n",
    "    \"OK\" if legal_repealed_count > 0 else \"WARN\",\n",
    "    \"Repealed legal articles are retained for transparency but excluded from retrieval indexing.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"RAG Safety\",\n",
    "    \"Repealed articles inside experimental KB\",\n",
    "    repealed_in_experiment_kb,\n",
    "    \"OK\" if repealed_in_experiment_kb == 0 else \"FAIL\",\n",
    "    \"Must be zero to prevent retrieval from repealed legal provisions.\"\n",
    ")\n",
    "\n",
    "\n",
    "# FAQ dataset\n",
    "add_summary(\n",
    "    \"FAQ Dataset\",\n",
    "    \"Clean FAQ records\",\n",
    "    int(len(df_faq)),\n",
    "    \"OK\" if len(df_faq) > 0 else \"FAIL\",\n",
    "    \"FAQ records after cleaning and duplicate removal.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"FAQ Dataset\",\n",
    "    \"FAQ indexing records\",\n",
    "    int(len(df_faq_indexing)),\n",
    "    \"OK\" if len(df_faq_indexing) > 0 else \"FAIL\",\n",
    "    \"FAQ records included in the experimental knowledge base.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"FAQ Dataset\",\n",
    "    \"FAQ evaluation records held out\",\n",
    "    int(len(df_faq_evaluation)),\n",
    "    \"OK\" if len(df_faq_evaluation) > 0 else \"FAIL\",\n",
    "    \"FAQ records reserved for evaluation and excluded from the experimental KB.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Evaluation Safety\",\n",
    "    \"FAQ leakage between indexing and evaluation\",\n",
    "    faq_leakage_count,\n",
    "    \"OK\" if faq_leakage_count == 0 else \"FAIL\",\n",
    "    \"Must be zero to avoid inflated retrieval scores.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Evaluation Safety\",\n",
    "    \"FAQ evaluation records leaked into experimental KB\",\n",
    "    faq_eval_leakage_in_kb,\n",
    "    \"OK\" if faq_eval_leakage_in_kb == 0 else \"FAIL\",\n",
    "    \"Must be zero because evaluation questions should not appear in the experimental retrieval base.\"\n",
    ")\n",
    "\n",
    "\n",
    "# Knowledge base\n",
    "add_summary(\n",
    "    \"Knowledge Base\",\n",
    "    \"Experimental KB records\",\n",
    "    int(len(df_kb_experiment)),\n",
    "    \"OK\" if len(df_kb_experiment) > 0 else \"FAIL\",\n",
    "    \"Experimental KB contains active legal articles and FAQ indexing records only.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Knowledge Base\",\n",
    "    \"Full production KB records\",\n",
    "    int(len(df_kb_full_production)),\n",
    "    \"OK\" if len(df_kb_full_production) > 0 else \"FAIL\",\n",
    "    \"Production KB contains active legal articles and all clean FAQ records after evaluation.\"\n",
    ")\n",
    "\n",
    "\n",
    "# Chunking\n",
    "add_summary(\n",
    "    \"Chunking\",\n",
    "    \"Structural chunks\",\n",
    "    int(len(df_structural_chunks)),\n",
    "    \"OK\" if len(df_structural_chunks) > 0 else \"FAIL\",\n",
    "    \"Chunks generated using the safe structural chunking strategy.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Chunking\",\n",
    "    \"Fixed-size chunks\",\n",
    "    int(len(df_fixed_chunks)),\n",
    "    \"OK\" if len(df_fixed_chunks) > 0 else \"FAIL\",\n",
    "    \"Chunks generated using the fixed-size baseline strategy.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Chunking Safety\",\n",
    "    \"Repealed legal chunks - structural\",\n",
    "    structural_repealed_chunks,\n",
    "    \"OK\" if structural_repealed_chunks == 0 else \"FAIL\",\n",
    "    \"Must be zero to ensure repealed legal articles were not chunked for retrieval.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Chunking Safety\",\n",
    "    \"Repealed legal chunks - fixed-size\",\n",
    "    fixed_repealed_chunks,\n",
    "    \"OK\" if fixed_repealed_chunks == 0 else \"FAIL\",\n",
    "    \"Must be zero to ensure repealed legal articles were not chunked in the baseline.\"\n",
    ")\n",
    "\n",
    "\n",
    "# Evaluation dataset\n",
    "add_summary(\n",
    "    \"Evaluation Dataset\",\n",
    "    \"Total evaluation questions\",\n",
    "    int(len(df_eval)),\n",
    "    \"OK\" if len(df_eval) > 0 else \"FAIL\",\n",
    "    \"Unified evaluation dataset including FAQ, legal article questions, and out-of-scope tests.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Evaluation Dataset\",\n",
    "    \"FAQ evaluation questions\",\n",
    "    int((df_eval[\"eval_type\"] == \"faq_retrieval\").sum()),\n",
    "    \"OK\",\n",
    "    \"Held-out FAQ questions used for retrieval evaluation.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Evaluation Dataset\",\n",
    "    \"Legal article evaluation questions\",\n",
    "    int((df_eval[\"eval_type\"] == \"legal_article_retrieval\").sum()),\n",
    "    \"OK\",\n",
    "    \"Manual legal questions linked to gold legal article references.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Evaluation Dataset\",\n",
    "    \"Out-of-scope evaluation questions\",\n",
    "    int((df_eval[\"eval_type\"] == \"out_of_scope\").sum()),\n",
    "    \"OK\",\n",
    "    \"Questions used to test refusal behavior outside Saudi Labor Law.\"\n",
    ")\n",
    "\n",
    "\n",
    "# Diversity / metadata\n",
    "add_summary(\n",
    "    \"Metadata Coverage\",\n",
    "    \"Unique legal chapters\",\n",
    "    int(df_articles[\"bab_title\"].replace(\"\", np.nan).nunique()),\n",
    "    \"OK\",\n",
    "    \"Number of unique legal chapters represented in the cleaned legal dataset.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Metadata Coverage\",\n",
    "    \"Unique FAQ sectors\",\n",
    "    int(df_faq[\"sector\"].replace(\"\", np.nan).nunique()),\n",
    "    \"OK\",\n",
    "    \"Number of unique FAQ sectors represented after cleaning.\"\n",
    ")\n",
    "\n",
    "add_summary(\n",
    "    \"Metadata Coverage\",\n",
    "    \"Unique FAQ subsites\",\n",
    "    int(df_faq[\"subsite\"].replace(\"\", np.nan).nunique()),\n",
    "    \"OK\",\n",
    "    \"Number of unique FAQ subsites represented after cleaning.\"\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Create DataFrame and save\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "summary_df = pd.DataFrame(summary_rows)\n",
    "\n",
    "summary_json = {\n",
    "    row[\"metric\"]: {\n",
    "        \"category\": row[\"category\"],\n",
    "        \"value\": row[\"value\"],\n",
    "        \"status\": row[\"status\"],\n",
    "        \"interpretation\": row[\"interpretation\"]\n",
    "    }\n",
    "    for _, row in summary_df.iterrows()\n",
    "}\n",
    "\n",
    "with open(REPORTS_DIR / \"dataset_summary.json\", \"w\", encoding=\"utf-8\") as f:\n",
    "    json.dump(summary_json, f, ensure_ascii=False, indent=2)\n",
    "\n",
    "summary_df.to_csv(\n",
    "    REPORTS_DIR / \"dataset_summary.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "summary_df.to_excel(\n",
    "    REPORTS_DIR / \"dataset_summary.xlsx\",\n",
    "    index=False\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Final safety assertion\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "failed_summary = summary_df[summary_df[\"status\"] == \"FAIL\"]\n",
    "\n",
    "assert failed_summary.empty, (\n",
    "    \"Dataset summary contains failed checks:\\n\"\n",
    "    + failed_summary.to_string(index=False)\n",
    ")\n",
    "\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Display\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "display(\n",
    "    summary_df\n",
    "    .style\n",
    "    .set_caption(\"Academic Dataset Summary\")\n",
    "    .set_properties(**{\n",
    "        \"text-align\": \"left\",\n",
    "        \"white-space\": \"normal\",\n",
    "        \"font-size\": \"12px\"\n",
    "    })\n",
    "    .set_table_styles([\n",
    "        {\n",
    "            \"selector\": \"th\",\n",
    "            \"props\": [\n",
    "                (\"text-align\", \"center\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"background-color\", \"#f2f2f2\")\n",
    "            ]\n",
    "        },\n",
    "        {\n",
    "            \"selector\": \"caption\",\n",
    "            \"props\": [\n",
    "                (\"caption-side\", \"top\"),\n",
    "                (\"font-size\", \"16px\"),\n",
    "                (\"font-weight\", \"bold\"),\n",
    "                (\"text-align\", \"left\")\n",
    "            ]\n",
    "        }\n",
    "    ])\n",
    ")\n",
    "\n",
    "print(\"Academic dataset summary saved successfully.\")\n",
    "print(REPORTS_DIR / \"dataset_summary.csv\")\n",
    "print(REPORTS_DIR / \"dataset_summary.xlsx\")\n",
    "print(REPORTS_DIR / \"dataset_summary.json\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e8a72f5-02d9-49d8-8c61-257b1169bbfa",
   "metadata": {},
   "source": [
    "### Interpretation — Academic Dataset Summary\n",
    "\n",
    "The academic dataset summary consolidates the main outputs of the data preparation stage.\n",
    "\n",
    "It reports the size of the cleaned legal dataset, the number of active and repealed legal records, the number of FAQ records used for indexing and evaluation, the size of the experimental and production knowledge bases, and the number of generated chunks.\n",
    "\n",
    "The most important validation points are that repealed legal articles are excluded from the experimental RAG knowledge base and that FAQ evaluation records do not leak into the indexing set. These checks strengthen the credibility of the later retrieval results.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42fa3a19",
   "metadata": {},
   "source": [
    "## Stage 14.0 — Visualisation Dependencies\n",
    "\n",
    "This optional cell installs Arabic text-rendering helper libraries if they are not already available in the environment.\n",
    "\n",
    "For reproducible execution, dependency installation is preferably handled before running the notebook. If the environment is already configured, this cell can be skipped.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "42f76f33-66a0-4757-bbb2-acb5ebfa631d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: arabic-reshaper in C:\\Users\\PC\\anaconda3\\envs\\datacolection\\Lib\\site-packages (3.0.1)\n",
      "Requirement already satisfied: python-bidi in C:\\Users\\PC\\anaconda3\\envs\\datacolection\\Lib\\site-packages (0.6.10)\n"
     ]
    }
   ],
   "source": [
    "!pip install arabic-reshaper python-bidi"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbca6bb0",
   "metadata": {},
   "source": [
    "## Stage 14.1 — Academic Visualisation Setup\n",
    "\n",
    "This stage configures common plotting settings used by the academic figures in this notebook.\n",
    "\n",
    "The goal is to keep all figures consistent, readable, and suitable for inclusion in the project report.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "ac22e80b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Visualisation setup is ready.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 14.0 - Visualisation Setup\n",
    "# إعدادات مشتركة لكل الرسومات\n",
    "# =========================================================\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "FIGURES_DIR.mkdir(parents=True, exist_ok=True)\n",
    "REPORTS_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "try:\n",
    "    import arabic_reshaper\n",
    "    from bidi.algorithm import get_display\n",
    "\n",
    "    def fix_arabic_label(text):\n",
    "        text = str(text)\n",
    "        if text.strip() == \"\":\n",
    "            return text\n",
    "        return get_display(arabic_reshaper.reshape(text))\n",
    "\n",
    "except Exception:\n",
    "    def fix_arabic_label(text):\n",
    "        return str(text)\n",
    "\n",
    "matplotlib.rcParams[\"font.family\"] = [\"Tahoma\", \"Arial\", \"DejaVu Sans\"]\n",
    "matplotlib.rcParams[\"axes.unicode_minus\"] = False\n",
    "\n",
    "\n",
    "def save_current_fig(filename):\n",
    "    path = FIGURES_DIR / filename\n",
    "    plt.tight_layout()\n",
    "    plt.savefig(path, bbox_inches=\"tight\", dpi=300)\n",
    "    plt.show()\n",
    "    plt.close()\n",
    "    print(\"Saved figure:\", path)\n",
    "\n",
    "\n",
    "def add_bar_labels(ax, values, horizontal=False):\n",
    "    if horizontal:\n",
    "        for i, v in enumerate(values):\n",
    "            ax.text(v, i, f\" {int(v)}\", va=\"center\", fontsize=10)\n",
    "    else:\n",
    "        for i, v in enumerate(values):\n",
    "            ax.text(i, v, f\"{int(v)}\", ha=\"center\", va=\"bottom\", fontsize=10)\n",
    "\n",
    "\n",
    "def set_boxplot_labels(ax, labels):\n",
    "    # Compatible with older Matplotlib versions that do not accept boxplot(labels=...)\n",
    "    ax.set_xticks(range(1, len(labels) + 1))\n",
    "    ax.set_xticklabels(labels)\n",
    "\n",
    "# Ensure chunk length columns exist\n",
    "for df_chunks in [df_structural_chunks, df_fixed_chunks]:\n",
    "    if \"chunk_word_len\" not in df_chunks.columns:\n",
    "        df_chunks[\"chunk_word_len\"] = (\n",
    "            df_chunks[\"chunk_text\"].fillna(\"\").astype(str).str.split().apply(len)\n",
    "        )\n",
    "    if \"chunk_char_len\" not in df_chunks.columns:\n",
    "        df_chunks[\"chunk_char_len\"] = (\n",
    "            df_chunks[\"chunk_text\"].fillna(\"\").astype(str).str.len()\n",
    "        )\n",
    "\n",
    "print(\"Visualisation setup is ready.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "88cf01a6-1477-4e94-bdaf-d49f8ecb1ee9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>stage</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Raw legal rows</td>\n",
       "      <td>249</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Clean legal audit records</td>\n",
       "      <td>249</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Active legal records indexed</td>\n",
       "      <td>211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Repealed legal archive</td>\n",
       "      <td>38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Raw FAQ rows</td>\n",
       "      <td>711</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Clean FAQ records</td>\n",
       "      <td>703</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>FAQ indexing set</td>\n",
       "      <td>503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>FAQ evaluation set</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                          stage  count\n",
       "0                Raw legal rows    249\n",
       "1     Clean legal audit records    249\n",
       "2  Active legal records indexed    211\n",
       "3        Repealed legal archive     38\n",
       "4                  Raw FAQ rows    711\n",
       "5             Clean FAQ records    703\n",
       "6              FAQ indexing set    503\n",
       "7            FAQ evaluation set    200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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JkJFJVXO5n7ioglylQRRA9ZwVzurQektt9ziJvI0SazJdd2PGqLOmTPH9W8IXI19+vRpN1GuSWbVlVcT2fHjx9vJkyfdJKlWk9esWdOVOtFkr8q9fPvttzEmbytXruwarip7I0OGDK5skkqkKPtB/SPiovtXE2rdh0qfaEJXwRtNGOv5U9kVPd6Enutw7yfwMWsCWaVc1DBW96dJTq1w/+uvv1wt/LO5X00Q63lUkEfBmptuusmtsNckqlbMt2/fPqx94hqnHTp0sNdee831CdAEcKD33nvPfVZQ41x/RkL0+6v0jehvHdqTQM+ZJpg1Ga+f+eijj7qyRA8//LB/Pz1XmlhXqR8FoBLDG2f6ndRzQK/j+IT7WnzkkUfcOPvjjz/svvvu82dA6HvUjFmBNW1TUERN1DW+9Tuqn4iCDxofGqvqN6LJezWC9uhvOHbsWPcaVeBHj8ej3iQqAaSAi3oSnAtN7CtYoMegxuj6e6nk2r///uvGgoIFyvzQ2P3888/d2FZQ8WxoLClAqWDI1Vdf7Z53HSc0vjQOFBRRUEXPlTJNAmmbRHJGFwAAQFh8AAAAiEpXXXWVT6dzP//8c5z7vP32226fLl26xHtfW7Zs8WXPnt1XpEiRoO2NGzd2379nz56wHlNc9xObQYMGuft+/PHHw7rvgwcP+vLkyePLly+f748//vBvP3XqlO+2225z9zVixAj/9osuushtu/HGG3379+932zZv3uzLlSuX296oUSPfhg0b3PbDhw/7qlSp4ravWrUqxn10797dt2/fPv/2IUOGuO1169b1b/O+33P8+HH3/RdccEHQ45VevXq5fadMmZLgc3229+M95rZt2/q2b9/u337vvfe67c8+++xZ3+/48ePd148++mjQfjt37vR16tQp7H3isnjxYve9V199ddD2HTt2+NKnT++7/PLLE/0z4nrNnDx50te3b1+3vUWLFjG+R+NTt02bNs2/rVq1ar506dK58R46ngcOHOhLCo888oi7P31UqlTJ9+CDD7rH4I3lc30t3nTTTe4+A//mmzZt8mXNmtWN4b179/q3nzhxwnfllVfGeF1ozBQrVizGz3zggQfcvhMnTgzarudE26dOnRrvY966davbT48j0MaNG301a9YMOl7UqFHDlyFDBt/XX38dtO9zzz3n9rvzzjv929q3bx/jd9B40bZf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zTVWv379GJkImTJlivN7w9kHOBe7du2yp556Ks7ba9asad27d3f/V0mtd9991/7880/Lnz+/tWvXzipWrOjf98yZM/bdd9/ZwoULbf/+/VakSBFr27atVahQgT8OAADJjAwDAAAAAIgiI0eOtH379gVlFwApLUuWLC4oEPqhkllTp061b775xu23detWq169uk2ZMsUuuugi27Bhg/v6008/9d/XVVddZS1atLDt27e7fRYsWGCVKlWyl19+OQV/QwAA0gYyDAAAAAAgSvzzzz/20ksv2XXXXWd169ZN6YcD+OXJk8efQRDoo48+clkx7du3d18/+uijdvLkSZs7d65lz57dbdPXPXr0cEGCrFmzms/ns59//tkFEqRPnz7WoEEDe+yxx9x+ZMgAAJB8yDAAAAAAgCgxfPhwO3jwoD399NMp/VCABKm0kMZq1apVXdmhEydO2GeffWYtW7b0BwtEt6mk0bx589zXKlfkBQskXbp0VqZMGTt27JidOnWKZx4AgGREwAAAAAAAosCePXtcSZZWrVpZnTp1UvrhAAnSxP/vv//uehto0l89C44ePWoXX3xx0H7lypVzn5cvX+4+FytWLOj2LVu22FdffWW33HKLZcuWjWceAIBkRMAAAAAAAKLA0KFD7ciRI2QXICooE0B9NqpVq2Y33XST2/b333+7z7ly5YpRzijwds/EiRPd99aqVcu6du1qkyZNOm+PHwCAtIoeBgAAAAAQ4Xbs2GGvvfaa3XDDDVa7du2UfjhAgt566y3766+/7JNPPnHZBaKSRKI+BYG8ngTHjx8P2q6Gx/Xr13c9DhQ8qFevnl1//fU8+wAAJCMyDAAAAAAgwg0ZMsTVb4+vd8ETTzzhJmIVVBCVb9HX+t6z2QdILAUGNKZq1qxpbdu29W/3ygmF9iHwAgWh5YaaNWtmDz/8sM2YMcMaNWpkHTt2tP379/MHAgAgGREwAAAAAIAIN2rUKBcwUGmWuKhO/IEDB+zff/+1//77z33W1/379z+rfYDEGjdunOs7oACXl10gxYsXd5//+eefoP337dsXdHtsrrzySleS65dffuEPBABAMqIkEQAAAABEuMyZMye4T8aMGd1HYvcBEkOBKPXbUHCrdevWQbep2XH+/PljTPqrMbKomffOnTtdhoLKEQXyMgtC+x8AAICkRYYBAAAAAABIEq+8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AgYAAAAAAABIE5555hnr3r27fffdd/b333+7Rse33367VatWze677z63T/v27a1y5crWp08fW716tStV1LVrV5dB0KtXL7fPsmXL7LLLLrNp06bZjh07bM6cOdalSxeXgdCvX78U/i0B4NxltAizePFie+ONN2K9rVOnTta0aVN/3bjJkye7A7fqx6kbfZ06dYL2D2cfAAAAAAAApA3Nmze3V155xQUHvDJEmi8aOHCgKyckmTNntrlz59pjjz1mLVq0sNOnT7usgYULF1rhwoXdPq+99pr7ePrpp23nzp2u70GrVq3c1zly5Ejh3xIAUlHAYP369TZx4kSX2qWacYG8g/K+ffvs8ssvt6xZs9qdd97pIr0NGjSwl19+2Xr06BH2PgAAAAAAAEg7NFekj4RceOGF9tZbb8V5e6VKldwcEwCkNhEXMPC0bNnSmjRpEuttQ4YMcY1mNm3aZPnz5/dHfxVkaNeunRUoUCCsfQAAAAAAAAAAQBT3MPjwww9dMMELBMjNN9/sGtTMmDEj7H0AAAAAAAAAAECEZxgorev999+3fPnyuXpxjRo1cttVX07NZDT5H6hs2bLu84oVK8LaBwAAAAAAADGV6j+LpwVx2vR8S54dIBWLuIBB/fr1bcKECe7///77r33zzTc2dOhQ12F+2LBhtmvXLndbzpw5g75PnepFHe7D2Scuu3fvtj179sToqyCnTp1yHwAAAAAiS+b0vpR+CIhgkXIdxzhFQhiriAaRMk4BJM/rNeICBmXKlHEfnr59+7qmxcOHD7f27dtb+vT/q6KkZsaB0qVL5247fvy4nThxIsF94jJ27FgbNGhQrLcdOnTIDhw4kKjfDwAAAEDSK5mTgAHiFinXcYxTJISximgQKeMUQMI0n53iAQOfz2crV660DBkyWOXKlf0T/Ilxxx132KRJk2zBggWuPFFs0RF9febMGcuWLZv7SGifuPTs2dM1RQ7NMGjTpo3lypXL8uTJk+jfBwAAAEDS2nI4HU8p4hQp13GMUySEsYpoECnjFEDCNJ993gMGjz/+uC1dutS+/vprt7L/6quvtvnz57vb6tSpYzNnzrRChQol6mco+CC6/+LFi7v/79+/P2gf9S2QEiVKhLVPXPRY43q8GTNmdB8AAAAAIsuJMwQMELdIuY5jnCIhjFVEg0gZpwCS5/Wa6OX/06dPtwce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QKQHDKpWrWpTp06N9TZtr1GjRmJ/BAAAAAAAAAAAiPSSRP369bMuXbrYunXrrE2bNm7b999/73oXDB8+3N59992keJwAAAAAAAAAACCSAwbt27e3HTt22IABA2z06NFuW6NGjSxTpkw2cOBAa9euXVI8TgAAAAAAAAAAEMkliZYtW2Z9+vSxLVu22EcffWSvvPKKK0W0adMme/LJJxP9AD/55BOrWLGiu99Av/32m3Xu3Nlq1apljRs3dsGK06dPn/U+AAAAAAAAAAAgCTIM6tataydPnrQCBQrYzTffnKTP6S+//GK33XabHT161Pbu3evf/scff1j9+vWtbdu29sYbb9jGjRutW7du9vvvv9u4cePC3gcAAAAAAAAAACRRhkHDhg3dZHxS2759u91www3WoEGDGLcNGjTIcubMaRMnTrTatWu7QIWyGSZMmGB//vln2PsAAAAAAAAAAIAkChi89NJL9uKLL1pSUkaBggUlS5Z0E/yBfD6fffHFF67EkPokeJo1a+ZumzVrVlj7AAAAAAAAAACAJCxJ1LFjR9u2bZt98803lj597PGHNWvWhH1/mtDv0qWLK0H0008/ua9DMw8OHTpkRYsWDdqu4IJXiiicfQAAAAAAAAAAQBIGDEqVKuU+ksqAAQPs66+/th9++MEKFy5sf//9d9Dt+/fvd59z5MgRtD1Xrlzu8759+8LaJy67d++2PXv2BG1bv369+3zq1Cn3AQAAACCyZE4fvNAICBQp13GMUySEsYpoECnjFEDyvF4THTD48ssvLal8+OGHNmzYMJs+fbpVq1Yt1n3OnDnjPmfOnDnGbenSpbPTp0+HtU9cxo4d6/ofxEZZCwcOHAj79wEAAABwfpTMScAAcYuU6zjGKRLCWEU0iJRxCiBhms8+7wGDpKSsAvUcePjhh92HeJP7r7zyin366ac2bdo09/WJEyeCvvf48eOufJGyCLxMgvj2iUvPnj2tXbt2MTIM2rRp474vT548SfTbAgAAAEgqWw6n48lEnCLlOo5xioQwVhENImWcAkhYfPPgUREwePzxx6179+5B29TLoFGjRtahQwd74IEHrESJEpYhQwbbuXNn0H5e6aLSpUuHtU9cChUq5D5ikzFjRvcBAAAAILKcOEPAAHGLlOs4xikSwlhFNIiUcQogeV6vEfUKj22y3pvkL1CggJUvX979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VSAaqeeA+hN07tzZff3ff/+5prEq3zJp0qSgbARPuXLl3Ofly5db5cqV/duzZcvmvw8gKamPwXvvvWfVqlWz6tWru22vvfaa+1Aj7/Lly8f4nvz581vevHndOA2lsbp3717+SAAAAAAAAGnMOQUMmjZtelb7x9aEE4h03377rb344ouuZIuaFkuvXr1s165d9tNPP1nWrFlj/T41l9Uq7/79+7u68ZrEXb9+vY0ZM8bdTiNwJCU16VYvg5MnT9r48ePdtqVLl7r+BK+++qrrbxAblSF68MEHXZaMAmPqgaBg1ueff+6yaooWLcofCgAAAAAAII05p4DB7Nmz4739l19+cROtBw4csAoVKpzrYwNSzLp161zT7hIlSrja7xkyZHDbNZG6Y8eOoLIv6lcgamrcqFEjmzt3rsvCuf/+++3yyy93deS16rtWrVpuv4oVK6bQb4XURsHYO++8037++WebMGGCazovClCdOnXKBQ304VG2zNatW12wS0Ev9ZjR/70m3RdeeKELPiiYwDgFAAAAAABIe84pYHDttdfGuv2PP/6wJ554wqZNm+YmWkeMGGG33357Yh8jcF5pQrV58+autrsm/zWJGph14AUIAgNoChZ88MEH1rJlS7ftoosuciu1vUldlS7SSu7cuXNb3bp1+YsiSShD4P3337eRI0faPffc499+yy23uCbboRTA1ceMGTMsS5Ysblw++uij7sMbpypFNGzYMLv66qv5KwEAAAAAAKQxiW56LJs2bXKToVOmTHGNNV966SXr0aOHm5ACoomyB6666io3carggNeo2JM5c+YY35MpUyb/59hu130dPHjQxo0bZ926dfP3MgASQyWvVOZq1KhRLnAQSBkCsZXM0liM7zZReaLChQtbhw4d+AMBAAAAAACkMYkKGPz99982ZMgQVwpDE1Aqb9G3b1+3MhuINv/88481btzYTfrPmzfPNTZOLNWEV4ku1YcvW7asC6wBifXUU0+5sm9vvvmmK0mUWMou2LJli79R8meffeayYQAAAAAAAJC2pD+Xb9q/f79b3VqmTBmbOHGiawS7YcMGFzAgWIBotXnzZlf7Xf0LNLYVBAv8UJ33cGnVtzIJ8ubNa127dnUli+bMmWPZs2dP1t8BaYNKZak0ljK5QsepGm2H6+jRo+6Yre+rXbu2bdy40fU2UJYNAAAAAAAA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7nUYEs+w+OKQDMXhrfRdIsg6bNiwmP1yySWXxIzMwo9zj05wFlQREFxlv8lsNR6nOisbIk9QdsSIEdEZgGs0rYz4PPNiqJzh+bSLo2OAtKUzYCBJm3nwHLp375531FFHxYEqPvnkk7xDDz00WriQiUCLDTbShSsUOnToEH8fN3zO9VB5yfZmLXN4wc0dG2OCBFkbBOZpsFHOzcQpCs+3H62Kws0VbdiybFh+z/oac0NGmfd1110X11EyZ2k7lA185wCM9ffII4/44kqqEB599NG4rmVzW0qaiUW7P9oVgfZCVCXQwpK/g8xZDq5oadSnT59S+u6lf6GtIOs4t71LLvaPhYd0S5vTtGnTopLluOOOK3ZeBpo2bVogWW/GjBl5O+64Y9yP07qNe36wlmnFyv3/XnvtFbMFGSjP9ZW1TutMHuO/t7Hrt7QlMGAgSf+FogbPkblAMIDSxgwBBYa+0j6DrAQyZplRQAkjw5UY2slQT4IF9J8l04HnSWWJUnLWKVkyWVAs602b9Y5Hy5Yt83bYYYdYu9K3yaK98sor44CLNUUFAVVYGVoMVa5cOVprFO41e/PNN8fHZHM1atQob9SoUb7wkioEsla5zmWB0U157sSJE+Pjl156KQ60qDwgmHD88cfnPfPMM6XwXUsFcT/EASoBK96rpdJEK1/uuw888MCNPrdbt255++67byTrMVeTYMDjjz8e9/Lck3N/vrE5bAykZ7+atcmUKoJKSZL0H+vatWtq0qRJuuqqq9LatWvjc3/729/SF198kX7wgx/Ex7NmzUo/+9nP0l/+8pf04osvpu7du6cGDRqkGTNmpJ133jm1aNEi/fCHP0wzZ85M06ZNS7Vq1Up169YloOtPRqXu888/T3//+9/jz6zZo48+Ol1zzTVpm222SU8++WSs33322SfdddddacmSJfG8W265JX366aepb9++/sS0Sb766qv0y1/+Mi1btiwtXLgwvfbaa2m//fZLJ598clwHccMNN6Q99tgjde7cOf/rvv766/j997//ffrggw9SlSpV0ksvvZTOOeccX3lJFUKlSv+6Rf/f//3fjT73t7/9bapTp07q1atXvH8fcMABsZ/87LPP4n15ypQpqWXLlqXwXUsFVa1aNfaP77zzTrr++ut9eVSquJc+//zz0+LFi9Ojjz5a4LGPP/449e7dO5199tnxMffy7EObN28ev5YuXZratWsX+9TJkyfHvX2zZs3iPr44/B3sVxs1avSd/79JpcWAgST9NxfRSpXisHT16tURNAAH/hgzZkzq0KFDOvfcc+MxbuC4kQMbF4IIHJaxQVmxYkWaOnVqfC3PW7VqVWrfvr0/G5U6NsesPQ5mr7jiinT77bfH57npYyM8atSoCIIRELvkkkvisQMPPDDWOWv++eef96emjbr33nvTyy+/nB566KG05557pr333jtNmDAhAgTdunVL69evj18ffvhhWrduXf7Xsca45nIt5YYP3/ve93zFJVUYHDzh4YcfLvF5XB85DLvuuuvSG2+8EdfGwkEHqSzxft64ceO0aNEifxAqddy7VK9ePV1++eURROXe5u67704NGzaMRL8skMU1l8cIsBJIqFy5cv7fcdRRR8U9eps2bdKPf/xjf4raqnyPMoOy/iYkaUvXsWPHCAKQ6UqWLNlcs2fPjg3KoEGD0ve///38506aNCmdd9556a233orsWDLCli9fHkECHnvwwQfTuHHjUqtWrcr0/0lbDwJWV155ZWyICX6xNRgxYkRUE2DkyJHpoosuSvPnz88Peg0cODACYX/+858jK5xs77Zt26Ybb7wxHX744WX8f6Qt4Zr5f//3f/nVBFS1EKBasGBBHH6deuqpcePGmuJaeNZZZ0VwoVq1aun+++8v629fkr4zBEvr1asXB1ivv/56XPeKct9990WQgCqtww47LJJOeE+WypM1a9bEoa1UFm699db0m9/8JipRCbDutNNO6Y9//GMkO2Woxtpxxx2jepruAZL+xdQDSdoMaJ2x3Xbbpcsuuyz/Y1q4kG3NJgRffvlluvPOOyMTm+ACwQLwvE6dOkXpI88hC8dggUoLB7WHHnpoql27dmR8k7FINlj//v3TRx99FM8ZOnRoOvbYY/ODBeAxMhg55N2wYUP60Y9+lObNm2ewQAXQnu3aa6+NiioOtEaPHp3fkogS73/+859pwIABqWnTprG+XnnllQgW8HW0w6KigMACa/CII47I/3pJqqjYH/7ud7+L92NaahSV30eyyZAhQ/LbXxDwN1ig8shggcrShRdemPbff/90zz33RDCAKuncYAGomqbdKo9J+rdtc/4sSfoP0UaDagJKH6kSICuWgy4qCerXrx8bFaoIaLvBZoQqhAwBAzJp2VBnQQSp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",
      "text/plain": [
       "<Figure size 1560x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved figure: saudi_labor_law_voice_agent_project\\05_reports\\figures\\01_data_completeness_vs_rag_safety_policy.png\n",
      "Interpretation: audit completeness is separated from retrieval safety; repealed articles are retained but not indexed.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Figure 1 - Data completeness vs RAG safety policy\n",
    "# =========================================================\n",
    "\n",
    "retention_df = pd.DataFrame({\n",
    "    \"stage\": [\n",
    "        \"Raw legal rows\",\n",
    "        \"Clean legal audit records\",\n",
    "        \"Active legal records indexed\",\n",
    "        \"Repealed legal archive\",\n",
    "        \"Raw FAQ rows\",\n",
    "        \"Clean FAQ records\",\n",
    "        \"FAQ indexing set\",\n",
    "        \"FAQ evaluation set\",\n",
    "    ],\n",
    "    \"count\": [\n",
    "        len(df_articles_raw),\n",
    "        len(df_articles),\n",
    "        len(df_articles_active),\n",
    "        len(df_articles_repealed),\n",
    "        len(df_faq_raw),\n",
    "        len(df_faq),\n",
    "        len(df_faq_indexing),\n",
    "        len(df_faq_evaluation),\n",
    "    ]\n",
    "})\n",
    "\n",
    "retention_df.to_csv(REPORTS_DIR / \"visual_01_data_completeness_vs_rag_safety_counts.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "display(retention_df)\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(13, 5))\n",
    "ax.bar(retention_df[\"stage\"], retention_df[\"count\"])\n",
    "add_bar_labels(ax, retention_df[\"count\"].values)\n",
    "ax.set_title(\"Data Completeness vs RAG Safety Policy\")\n",
    "ax.set_ylabel(\"Number of records\")\n",
    "ax.tick_params(axis=\"x\", rotation=30)\n",
    "ax.grid(axis=\"y\", alpha=0.25)\n",
    "save_current_fig(\"01_data_completeness_vs_rag_safety_policy.png\")\n",
    "\n",
    "print(\"Interpretation: audit completeness is separated from retrieval safety; repealed articles are retained but not indexed.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f975d07-33ee-449a-8ee1-d62a4fb475b6",
   "metadata": {},
   "source": [
    "### Interpretation — Data Completeness and Retrieval Safety\n",
    "\n",
    "This figure explains the distinction between preserving the full legal dataset for auditability and restricting the retrieval corpus for safety.\n",
    "\n",
    "All cleaned legal records are retained in the audit dataset, including repealed provisions and valid legal variants. However, the experimental RAG corpus includes only active legal articles and approved FAQ indexing records. This design reduces the risk of retrieving invalid legal content and supports a more reliable legal assistant.\n",
    "\n",
    "The FAQ split also supports fair evaluation by keeping a separate held-out subset for testing.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "71a02818-0ba7-4e4b-9d1e-62f7fd1edfac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>split</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Indexing</td>\n",
       "      <td>503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Held-out evaluation</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Leakage overlap</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 split  count\n",
       "0             Indexing    503\n",
       "1  Held-out evaluation    200\n",
       "2      Leakage overlap      0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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1wUg7dDNGEBcUOIijf1UhVLd+BRkKhibPHmy7d+/3wUQsmzZMlfZPOuss5LtyqqxrwpStE9VZm+44YaI26nCoqBElZLHHnvMBcgKbE9ElUl1TVblWs/Xed17772ukt2jR4+oX7cCU1X21TqsfXpdohWYJEUVLVWWJk6caE2aNHEVdrnwwgtd0HXNNde4farlWpUsBW16XerCrfV6b8L3p4AttRTgixJSeRSs6P1QJU/BoQIeVZwV1K9Zs8adl16rWtNVIVdArHUeBUleEK6gtnbt2i6APVF3zmiOe/HFF7tAf+bMme6zDB0rqGPqu6PPVmMhFURu2bLF/a1Ksb6fCmSGDx/u7lWJTsuswEpEpp4DH374oQviQ6mLt34/aj30smerQl+vXj1XGVdysy+//NJ1p1ew98gjj8TsvKI5llos1e1fvSg0JlO9JRRAiffdjeSzzz5zAZd++wpoFaAouOvTp4/7vahsCP2t6ren74fGk6vLr573888/u9+DWlAjBXahVF7oO6bP0xtr7wWvanlVEPm///0vwXclmvGyCoT0/dE56Dvp9f4If46C15UrV7px4zp3/Z40Jn758uXudyx6zSon9F277rrr3O9Fv2kN49CwDL0vKb0gFe35nSz9Nq666ioXbOvcdeFAr+3ll192ZbPeY++cNSxE5ZPef43J1/jqCRMmuKztW7dutQEDBiR5HF2I0Get74QuZHllaUr2qe+LLozp96//f3RRR/vVcJPUvC4AaSgAAGnozjvv1KXvJG/Vq1d3202YMME97tWrV/C5t99+u1v26aefBpd98803blnjxo1PeOyHH37YbfvCCy8ku924ceMCmTJlctuWKlUq0KVLl8B7770XWL16daJtb7zxRrfd1VdfHVi2bFmC88qSJUsgb968gT179rhlt912m9t2zpw5id6PH3/8Mbhs8ODBbtkHH3wQiNZbb73lnvPiiy8Glx05ciRw1llnBXLmzBn4+eefE2z/0EMPue0feeSR4LJ69eq5ZZUqVXLvsXfeybnlllvccyZOnBhcduzYscAzzzzjlteuXTu4fOHChe49ufjiiwO7d+8OLt+/f3+gTp06gaxZswbWrl0bPHc9/7zzzkt0zOXLlwe/L23atAnMnz/fbS8bN250y6+88sqTOu7TTz/tnv/ss88mOObo0aPd8v79+yf7fjRr1sxt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ct2P77vvPreNAt0LL7zQJkyYYFu2bLHp06dbx44drVKlStarVy8+MwAAAGR4cTfPrDK9btiwIeI6JcBRhd+jViptmy9fPtcFM5JotgFipVGjRm5M62233eaC2QIFCrgW2X79+rlpekT3P/zwg/Xu3duuuOIKl724Xr16LtuxvuOiZFHDhw+3Pn362MaNG933XhmNBw4c6OaoBQAAADK6TIFI/SLT0ejRo10LlKYjyZ07d4J1TzzxhN1yyy3u75deeskGDBjgKvY7duxwXS81t2fZsmWD20ezTTQWL15sNWrUsEWLFrkWNgAAAABAbKU07orbbsbvv/++/fXXXwluXiD7+eefW48ePez11193XTSVOEfzel5//fXBMYvRbAMAAAAA8Ke4DWaT88ILL9h5553nxh6KunL27dvXJchRV81otwEAAAAA+FPcjZn1bN682VasWOHGuYaOdT18+LD9/PPPLqlOqLp167p7Jcq55JJLTrhNw4YN7XRRrs+k9D4FIMNa9Uzz9D4FAACADCnuglm1oJ599tnWv39/lwxKyW+U1fXtt9+2c88919asWeMS5oQnc/IS56xcuTKqbZKizLFbt25NsExBtWhe0PC5QeNB9sx0mwbSSzyWCQAAABmhXhV3wawyv3rzcYoG/1533XXWuHFjN43J3r173fI8efIkeF6OHDksU6ZMblxsNNskRRlklTQqEj0vfO7PeFA2L8EskF7isUwAAADwo+TiNF8Es+GUzUrTkXTo0MHNuVm7dm23XEFpOCV2ypIli7udaJukdO/e3dq2bZuoZbZVq1Zuep/QqYHixZq9iV8ngFMjHssEAAAAP1K8dVoFs1K5cmV3v27dOrvyyivd3/v3748YxYeOsU1um6QUL17c3SLJmjWru8Wbw8cJZoH0Eo9lAgAAQEaoV/kim7GSQUnRokWtdOnSlj9//uA4Vo+m35GqVatGtQ0AAAAAwL/iLpg9cOBAomXqXpw7d25r3ry56zrcrFkzmzVrlh05ciS4zQ8//BBcF802AAAAAAD/irtgtn79+tajRw/77rvv7LfffrMnnnjC3nnnHXv66aetTJkybhstU5Knbt26uXljP//8c5e0qWvXrsFW12i2AQAAAAD4U9wN9urdu7driVXgqal5KlSo4B5fe+21wW2qVatms2fPtmeeecYFp+pS/Nhjj9l9992X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9iXYbv78+damTRs755xzrF69ejZkyBA7cuRIircBAAAAAGTAltmsWbPaW2+9Zd26dXPdipXBWGNor7jiCjfPbEp16tTJVq9ebQMHDrTatWvb3Llz7d5773Xz2HrJpP78808X5N588802btw4+/fff61r1662bNkyGzlyZNTbAAAAAAAyaDDryZMnj1WpUsXKlCljd955ZzDTseaYVSKoaJ177rn26aefWtGiRd3jatWq2W+//ebmrF25cqVr9X3qqaesYMGC9vrrr7tgWsdQa+79999vvXr1sqpVq0a1DQAAAAAgg3Yz3rNnj914440uCO3YsaMbP+tRIPnSSy+laH9Dhw4NBrKeY8eOWebMmV1QHAgE7JtvvrHLL7/cBameK6+80q37+uuvo9oGAAAAAJCBg1mNlf3ll1/svffec117Q91+++32xRdfpGh/ocGnTJ482d5//3039rZIkSK2bt0627t3r5UuXTrBdmeeeaa7/+uvv6LaBgAAAACQgbsZqwV07NixduGFFyZaV6dOHfv7779Par/qJvzCCy+4oLRv375uDK3s2LEj2K05lBJPyX///RfVNklRJmaN+w21YsUKd3/06FF3izfZMwfS+xSADCseywQAAICMUK9KdTC7fv16ly04kgMHDlimTJlOar9K+qRMxGr1VWZkJYVSC+3x48fd+mzZsiV6jo6lLsnRbJMUjc0dMGBAkl2qd+7cafGmbF6CWSC9xGOZAAAA4EeKt05pMFu+fHn74YcfrFWrVonWqYuwptc5GcqIrJsSQKmlVEmb7r77bitevLhbf+jQoQTbHzx40I2HzZcvn7udaJukdO/e3dq2bZuoZVavT89TUql4s2bvyV0wAJB68VgmAAAA+FFycVqaBLMaF9ulSxfbtm1bMKBVS4UCWbWo9u/fP7WHCAbES5cutfPPP9+Nq92wYUOCbTZt2uTule24bNmyJ9wmKQqWvYA5nPYZPqY3Hhw+TjALpJd4LBMAAAAyQr0q1QmgFLC2bt3aBbXFihVzywoVKuTmd9U8s/fcc0/U+9JY11GjRiVariBWKlWq5LoOX3LJJTZnzpwE22j6HmnYsGFU2wAAAAAA/CvVweyRI0fsnXfesblz57pWWE3No4RNU6dOdYmhsmTJEvW+NJa1a9eubj7Y/fv3u2WzZs2y5557zpo3b+6m2pGePXu6jMQaQ+sFwYMGDbK6detagwYNot4GAAAAAOBPmQIaRJrKpuBYZfPUfhRwjh492tasWeOyDyuJ1B133GFPP/10MBuxl6hJwbMSOinjcf369W3kyJFWpkyZFG0TjcWLF1uNGjVs0aJFVr16dYs35fpMSu9TADKsVc80T+9TAAAAOC2kNO5KdTBbq1YtmzJlipUoUcJiadeuXbZv3z7XdTlSVmJR1mJNpaMgNzTQTek2J0IwCyApBLMAAACxkdK4K9XdjAcPHmwjRoywWCtQoICVLl06yUBWMmfObCVLlkw2SI1mGwAAAACAv6Q6DafGy86cOdMWLlzoAsdIxo0bl9rDAAAAAAAQu2BWiZ+yZ89uv/zyS2p3BQAAAADAqQlm161bl9pdAAAAAACQIqkeMwsAAAAAwKlGMAsAAAAA8B2CWQAAAACA7xDMAgAAAABO/2A2f/78CR6/9957sTwfAAAAAABiH8weOHDADh48GHzcpUuXlO4CAAAAAIBTG8xWqlTJRo0albqjAgAAAABwKueZfeyxx6xjx4725JNPWsmSJd2yqlWrJvucv/766+TPEAAAAACA1AazHTp0sMqVK9uHH35oa9assQULFli5cuVSuhsAAAAAAE5dMCv16tVzN7nooovsm2++OfkzAAAAAADgVASzoebOnesSQqmldtq0abZ9+3YrXLiwXXHFFa4VN2fOnKk9BAAAAAAAsQ1md+zY4QLXhQsXWvbs2V0gq4B2zJgx9uqrr7oAt1ChQqk9DAAAAAAAJ5/NOFzfvn3t0KFDNmPGDNdCu3HjRvdYQaweK2EUAAAAAABxFcx+8cUXbqqeyy+/3DJlyuSW6b5hw4Zu+fjx42NxngAAAAAAxC6Y/e+//+ycc86JuK5atWquyzEAAAAAAHEVzJYtW9Z1MY5k6tSpbj0AAAAAAHEVzHbu3Nndhg0bZkuWLLEtW7bY4sWL7cUXX7QuXbq4dQAAAAAAxFU24z59+tjSpUvtgQceSLSuY8eO1rt379QeAgAAAACA2AazWbNmdXPM9uzZ03Ur1hjZIkWKWOPGja127dqp3T0AAAAAALEPZj1169Z1NwAAAAAA4n7MLAAAAAAApxrBLAAAAADAdwhmAQAAAAAZL5g9dOhQbM4EAAAAAIBTFczmyZMntbsAAAAAAODUBrM1atSwzZs3p3Y3AAAAAACcumB28ODBNmLEiNTuBgAAAACAUzfP7DvvvGMzZ860hQsXWubMkWPjcePGpfYwAAAAAADELpidO3euZc+e3X755ZfU7goAAAAAgFMTzK5bty61uwAAAAAAIH3mmZ0xY4a99NJLNmjQoOCyr776yrZs2RKrQwAAAAAAEJuW2e3bt1u7du1s6tSpwWWPPfaYu584caL99NNPLkkUAAAAAABx0zL70EMP2aZNm1wr7MaNGxOs69KliwtoAQAAAACIq5bZadOmuYC1Zs2aidade+659s8//6T2EAAAAAAAxLZlVq2y5cqVi7huz549liVLltQeAgAAAACA2AazVapUsQkTJkRcN378eKtRo0ZqDwEAAAAAQGy7Gd9777125513uil6WrVq5ZatWLHCJk+ebH379nUZjgEAAAAAiKtgVoHsypUrXQbjRx991C2rXLmyu7/77ruta9euqT9LAAAAAABiGczKkCFDrFu3bjZlyhTbvHmzFS5c2Bo3buwSQAEAAAAAEJfB7NKlS23o0KH2559/2pYtW6xkyZIu+dNZZ51l+fPnj8UhAAAAAACIXQIoJX9SC+yYMWPsyJEjLrPxzp07beDAgVanTh1bv359ag8BAAAAAEBsg9nevXtb586dXffi3377zaZOnWpLliyx5cuXW4kSJaxnz56pPQQAAAAAALHtZqzkTzNnzrS8efMmWK4W2jfffNMuvvji1B4CAACYuQvHmi1AswYUL17cGjVqFHEKPP2/PH36dDt+/LhddtllLo/FyWwDAMBp3TJbsWJF27FjR8R1ZcqUsezZs6f2EAAAZHgff/yxnXHGGfbqq69a5syZbfbs2Va7dm179tlnE7w39913nzVv3tx27dplBw4csLZt21qXLl1SvA0AAKd9y2z//v2te/fuNmnSJMuRI0eCdV999ZVdeumlqT0EAAAZnuZz1xR4AwYMsEyZMgWDUs3p3rp1a6tUqZJraVWwq8D3xhtvdNs0aNDABa5t2rRx99FsAwDAaRnM6j+6cHPmzHFBq7oWh9L42WrVqqXuDAEAgPv/N/z/2SuuuMIFpr/++qsLZj/66CN3Yfn6668PbtO0aVMrWLCgffjhhy5QjWYbAABOy2B27ty5iZYVKlTINm3a5G6hcufObatWrUrdGQIAgESBrHgzBuTMmdPd//7773bmmWcmGOKjLskKdLUu2m0AADgtg1l1cwIA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nlquZTpfjafV69J5Pfrooy67sbogK3GUrjYCQEqFt27u2bPHhg4d6srG8O1Upi5evNgNe/jkk0+sQIECrnxSV+JmzZq5ebB//fXXBM+J1DoSOnRDvVi8sbOhlHtgx44drrzznqOcA+GtuOq1ovIRQNpSRnENKdBvXffeb111F5UBSlQZSi2lGteuepiyD2tsvroDe9SzQ0OsvvjiC/dYrbWRepl5v32Nj1crrMoF9f5QLzePshqL93yvvGrdurXrFae6mFpvlf28cePGafQOIRYIZpHhaZypusLpXt1aQrvOvfDCC65QUwCoLi133nmnXXvtte5vbyyqKnEaP6YMmXfddZdL4a55EVVoqpBU4KvKmbrVqWBVopNRo0bZww8/7J4fWgFU918F1uJNuZNUBTKpBCdarmyfXkC8YMECd876z0Pnr242ShylMWcAEErlhG7qlqdM6JraS934VEYq8JSKFSu6+V+9suicc85x04apIhpeFoWWWRoHqwt/6jKorKPav+ZxVHdjlY3JBaChlVNVdjV+TpVMZRlVYPr333+7MbMqZ5VnwMvcrqEduqAXXsHW6wOQNtR1V+NXu3bt6soL/TY3b97sLjSpbqOL6+XLl3fj5r0LS3qOLnzp961ElgosFYjqgr8u/mveaA0fUFmji/9euaBtNUNDeHmhupcyHKvRQMOrNOzBK1d0YU25SyLVqXRftWpVl1BK5YrqgIhz6d00DMSLV199NUHXOWnfvn0gb968gYsvvth1pZN169YFcubMGejWrZt7XKdOnUDDhg0T7a98+fKuq4u6BauLcb58+dzz1G1G+x00aJDrwvLvv/8Gn7N27VrXdfiJJ55wXep0Pk899ZRbt3XrVvf4ySefdI937drlHj/66KMJjrt06dLAM888E1i/fr17HNqtRtTNT+fQq1evGL57APxs1apVrnvf8OHDA+eff777W2XUlClTAu+9914gf/78bgiFR9vUq1cv+LhatWqBRo0aJdinugdmyZIl8OCDD7rH11xzTaBo0aKBv/76K7jNqFGjXDk2f/5893j06NHu8dy5cxPsS8M4tPzXX38NdlFW12YNC9HywoULB+68887Atm3b0ugdAjI2lRHjx493XW5Du/5GMmbMmAS/V68uorqSyhLVX7wuvM8995xbrzqWHusYW7ZscX+XLl060KVLl8DQoUPd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Fi1aBJepR4TKCfXsUFJJJVsLHXowevRo9/jRRx91U//p74cffjgYvOo5CpJDKSDVdpoaS9SzRGWDEsAp2aVaZDVEQS2u2k4X94B4Fzm7BQAAPvHaa69Zv379kly/YcMGW7RoUcR1Sqxy/PjxRAlQvORu8vfff9s111xjt956q/3zzz8uydGKFSssa9aswe1+//13e/vtt+2BBx6wRo0a2aWXXuqSrhw+fNgOHjyY6Lj16tVz90uXLnWJk3RxecGCBQm2KVasmEuasnfvXqtTp46VKlXKRo4c6R4rOZReV1KU3EnJmpTYad++fe6clcAlZ86cST4HQOqp/NDvOaky54MPPnC/eSVX8+TLl89at27tEsupTFLyttq1a9vs2bNdAri//vrL3nrrLZd80itzvERNFSpUsC+//NJuv/12e/75561Nmza2f/9+u+6661wSt08++cQlf3r99ddtzJgxVrVq1eA+ChYsaD/99JNLCqUEUlOnTrUPP/zQnU+BAgVc0jcg3pHNGADga1999ZUL1p566qlE60IzcyqDryjIVBZfVQ4VLKrCpkD1pZdeclk49RxVDnfs2GGFChWyYcOGuUrkk08+6e6lTJkyLruoVyl85513XNCo51577bWuspotWzY744wzXMbicF42TwXSl112mdvv5MmT3d8yc+ZMVwlVpVjPV/D73nvvuSBVFU0FusowqgosgPgRWuZcdNFFidavW7fOZSlXYKkLTtpO9ypvlG1806ZNLvDU/fz5891FLK/MOOuss4IZxRWUqozRY+3vzTffdOVN//79rUGDBjZu3DjbuXOn3XbbbW47BcvKJKx9elmRZdu2bXbxxRe7GRhEZaKOr1kavPIOiGcEswAAX1PgqNYLtWZo6olQ3tQUoS2tN910k6vQqTKpqSemTZtmLVu2dIHjiBEjgpVRtaxomi21mKr1w5uay6Pt1JIir776asRzU4uuWlM1dcaZZ54ZXL5w4ULXslurVi0XmCooVTCtZZpK57PPPnPP69Kli3tdCmavvvpqVxHWelpMgPgPZiMpXry4awkdP36821a/fd2rjPGCR683R968eYPPmzVrlitHvCnDFHxqqpvQ46iHisrASZMmuakBFeDqFqpx48YJHv/888+uTNQ5qGxRrxNNOTZw4MCYvSdAmkrvfs4AAKSGMg/rv7OkkhgVLlw4cPnll7u/NeWWtp02bVqCbXr27OnGl2q6Gk25FZokRdmHI03D8/TTT7vtkpv+RtNRaFoMZUr3kstNnTo1UKBAATe+LTSD6BtvvBG48847AwMHDnTnoTG3SsgCwF+KFy/uZkSIxCs3/vzzz4jr161b58onbaPyYNmyZYFx48a5ZE4aUxs6HnfIkCGuvEgNTQ82duxYl+lYMzcwrh5+Q8ssAOC0aQlp1qyZa73Q37qpdVWtDV7rhbrZqWVD3fBE49PUjVfL1P1Y3XtbtWrluht7z1HrrsaSbdy4MdjlT6pVqxY8bmira6jy5cu75955551uG41Z1Ti1xx9/3Hr27BncTt0A1a0vnFpqAfivTAofA+/R7/zFF1+0u+66yyZOnOiGMnhj8/v06WMVK1Z0wyDeffddN5Tgiy++cN2A1ZIrDz74oCufpFevXqk+V42NbdeuXar3A6QXEkABAHztnHPOcUGfkp+oYqguuS+//LJt3brVdalTgKvxaEqCouBVVHk7++yzrXDhwta1a1eXTGnw4MEucFV3Yu3TC2Y11kxUufRorKvGySbXndBz/vnn22+//WZbtmxx49HUVfjhhx8OdhcEcPoFs0rSpgtg4TSsQMMiNFa1dOnSdsEFF7juwhovX716dTfmVTp37mzLly+3zZs3u0BW2+imBHO6+AXg/+KSLwDA17yxYxpnpuydRYoUSbBeLbOffvqpCzorVarkAlEFrao0KqCNVDH0kkCJWnGVIfTpp592ga72oWRMJUqUcElZvIQsJ6LAGUDG6S2ica4KWEMTPf3333+2ZMkSl8lcvUIUrGocrQJZLnABKcdlYQDAaVF5VIunusxFWieqTDZv3twFpKpQKqANDWQVDI8ePTr4nN27d7vkS6LpKvr27esCXGVBVmutWmZVWX3jjTdO2esEEP+8Mke9PtQLQ1N3qbeHug2rzBAle1IZdOWVV7rtCWSBk0PLLADA91QZHDt2rC1btsy1cISv8+ZnfOSRR9y4tP/9739uipv27du7LMYaK6txbJq+p0OHDm5eV2VJVtCr7KBq/dU4V93C9w0AoZSlXHNSa8w809sAaSuTskCl8TEAAEhTEyZMcNPraLodTTMRTtNeqNVWLSTywQcfuCkrVOHU9Bcat6ZWFLWSAAAAf6BlFgDge6FdiSMFs1o/b9481wqrlpKOHTu6GwAA8C9aZgEAvqcgVcmYlKzpq6++SrR+3759lidPnnQ5NwAAkDZomQUA+J5aWz///HMrV65cxPUEsgAAnH5omQUAAAAA+A5T8wAAAAAAfIdgFgAAAADgOwSzAAAAAADfIZgFAAAAAPgOwSwAAAAAwHcIZgEAAAAAvkMwCwAAAADwHYJZAAAAAIDvEMwCAAAAAHyHYBYAAAAA4DsEswAAAAAA3yGYBQAAAAD4DsEsAAAAAMB3CGYBAAAAAOY3/wf9D92DH8NPIQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 960x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved figure: saudi_labor_law_voice_agent_project\\05_reports\\figures\\05_faq_split_no_leakage.png\n",
      "Interpretation: leakage overlap must be zero to avoid inflated retrieval scores.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Figure 5 - FAQ no-leakage split\n",
    "# =========================================================\n",
    "\n",
    "faq_leakage_overlap = len(\n",
    "    set(df_faq_indexing[\"document_unit_id\"]) &\n",
    "    set(df_faq_evaluation[\"document_unit_id\"])\n",
    ")\n",
    "\n",
    "faq_split_df = pd.DataFrame({\n",
    "    \"split\": [\"Indexing\", \"Held-out evaluation\", \"Leakage overlap\"],\n",
    "    \"count\": [len(df_faq_indexing), len(df_faq_evaluation), faq_leakage_overlap]\n",
    "})\n",
    "\n",
    "faq_split_df.to_csv(REPORTS_DIR / \"visual_05_faq_split_no_leakage.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "display(faq_split_df)\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(8, 4))\n",
    "ax.bar(faq_split_df[\"split\"], faq_split_df[\"count\"])\n",
    "add_bar_labels(ax, faq_split_df[\"count\"].values)\n",
    "ax.set_title(\"FAQ Split for Retrieval Evaluation Without Leakage\")\n",
    "ax.set_ylabel(\"Number of records\")\n",
    "ax.tick_params(axis=\"x\", rotation=10)\n",
    "ax.grid(axis=\"y\", alpha=0.25)\n",
    "save_current_fig(\"05_faq_split_no_leakage.png\")\n",
    "\n",
    "print(\"Interpretation: leakage overlap must be zero to avoid inflated retrieval scores.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "20a26585-2435-42ea-8a8d-77bf30084ed4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>strategy</th>\n",
       "      <th>chunks_count</th>\n",
       "      <th>parent_records</th>\n",
       "      <th>mean_words</th>\n",
       "      <th>median_words</th>\n",
       "      <th>max_words</th>\n",
       "      <th>chunks_per_parent_record</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Fixed-size</td>\n",
       "      <td>719</td>\n",
       "      <td>714</td>\n",
       "      <td>83.02</td>\n",
       "      <td>68.0</td>\n",
       "      <td>500</td>\n",
       "      <td>1.007</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Structural</td>\n",
       "      <td>722</td>\n",
       "      <td>714</td>\n",
       "      <td>85.43</td>\n",
       "      <td>72.0</td>\n",
       "      <td>653</td>\n",
       "      <td>1.011</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     strategy  chunks_count  parent_records  mean_words  median_words  max_words  chunks_per_parent_record\n",
       "0  Fixed-size           719             714       83.02          68.0        500                     1.007\n",
       "1  Structural           722             714       85.43          72.0        653                     1.011"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7MAAAHUCAYAAADocH+kAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAATuRJREFUeJzt3Qd0VNX6/vE3IXQIAQVRqghXBVTKBQHhAjYUUJGigAUREEWvV8QKgiAKWLFiQwUrgkqzXKxwBUVApaMU6UWQIp0AyX89+7dO/plkhkyYIZmTfD9rzRpyZs85JzMTzjxn7/2euNTU1FQDAAAAAMBH4nN7BwAAAAAAyC7CLAAAAADAdwizAAAAAADfIcwCAAAAAHyHMAsAAAAA8B3CLAAAAADAdwizAAAAAADfIcwCAAAAAHyHMAsAAAAA8B3CLAAAAADAdwizAAAAAADfIcwCgA9t2bLF4uLirEWLFuZH3333nTVs2NCKFCliJUuWtLvuuivPvC45sQ+x8HuGsmbNGrdvl112Wb7eBwDAiUeYBYAgSpQo4b4MFy9e3LZt25bp8Xfffdc9/tRTT/H6ZdPixYtdyFi5cqXdfPPN1qVLF0tOTs7yeUuXLrVevXpZtWrVXAguU6aMNWrUyIYOHRr0PUL0LVy40Hr06GGnn366ew9OOukka9KkiQ0bNsy2b9/uu5d89uzZ7u+4atWqub0rNm3aNPd3oc+1Xlvt07/+9S979NFHbcWKFbm9ewAQkwizAHAM+/fvt6effprXKIpeeOEFF1715X3UqFH22muvuftj0ePnnnuujR492nbu3Gl16tSxpKQkmzt3rg0aNMgF3AULFvA+nUAjR460unXr2ptvvml///23ew8SExPtp59+sgEDBrj3YNmyZbwHx0EnZBRk9Teh17RevXpWuHBhmzlzpg0cONAee+yxtLYK37Vr1z5hr/O4cePcNhSiASDWEWYBIISKFStahQoV7KWXXvJlr1OsmjNnjpUqVcoaNGgQVvtJkybZ7bffbgUKFLAXX3zRtm7d6nrU/vjjD1u9erXddNNNtnfvXnpnTyAFnLvvvtsKFSpkr776atp7oNdfPezXXXed7d6923d/J+rZT01NdcOSc8u8efPs4YcfdsPtv/zyS7cvP/zwg/3+++9uOPnjjz/uemsBAJklBFkGADBzPSP/+c9/7M4773S9UvRURMeOHTtcmA2HenAVZOWtt96yrl27BjxeuXJlt1zzb+PjOT97Ihw4cMD9DXjD6zt06BDwuIYca/k///lP16OH7NHJGgXqPn362CWXXBLwWLly5ey+++7jJQWAEDjyA8AxaI7mqaee6obG7tq165jzQPVFvmPHjpkee/bZZ91jr7zySqbiPUuWLLFWrVpZsWLFrFKlSvbEE0+4Nn/++afdcMMNLvSddtpprkCSQkUw69ats86dO1vp0qXdXN82bdrY8uXLM7WbMWOGtW7d2rVTUNdQxeeff959kfak37e//vrLbr31Vtcr1KlTpyw/JxMmTLCmTZu6HibtR+PGje29995Le1w9eFq39lc3/Vu3k08+OeQ6J0+ebJs2bbL69etnCrLp3XbbbXbhhRcGLFPPrXoMtf/anyuuuCKgB+5437Os1huKejS1DvVIa5iuNw9Y751CuT4DZ599tl1//fWuZy5cx3r/1eunbWpeazCar6zHVZArlI8++sj1el9wwQWZgmx6+oyqTXqa6+ntmz4XV199tW3YsCHtcW//9DtnNGLECPfYmDFjMhV1ymq9oejz7r0e6s3XZzxjIa3j2c4nn3zienmLFi3qRnTo83Httde69fz3v/895j4dOXLE3etv8limT5+edrJA/294fz+66XVMv9/6/6Nnz55uKL5eWw3Hv+iii9yJB9UBUA+7PnO33HKL+2x79Peuz4RoeLO3/urVqwecYFKtAA371++r/6Muv/xyt41g0zQ0DUDb1ee7Zs2a9sgjj7j/67Rvcs8997ht6L3JaN++fe511wiZo0ePHvP1AZA/0TMLAMegQiz333+/+6KugDN48OCovV4KHPoCrC+XZ555pvuCqm0dPHjQXn/9dRd4tFzzEJ977jn3ZVCFdtL77bff7JxzznGB9KyzznJB6/PPP7eff/7ZzSE95ZRTXDutT19Uy5cv78KbvoR+9dVXrud51apVbv3prV+/3s3b070cPnz4mL+LvrBq3p++yOvLsHpJtR/6Iq2iQd5QSQ2nfOaZZ9wX4gceeMA9V7/Xsb7AS/v27bP12mqIpuZ0Sq1atWzt2rX26aefut/n119/Pe4exONd74cffuh63vRcDSVVAJg/f74LVXqtdLJA75XeMw3pVcjKKgSF8/6rt1SP//jjj+5kQvpQomHBOllwxhlnHLMq8vG+B4sW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Y5g0aZJdddVVlhXCbBjUI+u9qNWrVw/nKQAAAACAbFi5cqXrRPTyV1YIs2HwhhYryNaqVSs77wcAAAAAIBvCndpJmAUAAEC+t3//fqtZs2bI1+Hcc8+1KVOmuPl8b775pn3zzTe2bds2q1Klit14443WtWvXtLbhtAEQOcIsgIgtWbLEli1bFvLxxo0bW4UKFQKWadh+3bp13QE+o+TkZPvxxx9t7969VqdOnUzPBQAg2ooWLWrTp0/PtDwlJcVatGhh+/btcz/fcsst9ttvv9nQoUPdMeqLL76w66+/3lavXm0DBgwIuw2AyBFmAURs0aJF9tFHH2VavnPnTvv2229twoQJ1rFjx7Tlq1atsquvvtreeustu+mmmwKe891337lliYmJdtJJJ9ns2bPtzjvvtBEjRlh8PFcTAwCcGHFxcVa1atVMy99++23X0/riiy+6n88++2y3rGzZsu7n2rVruxA8fPhwe/DBB92xKpw2ACJHmAUQsc6dO7tbRnfffbf973//s/r167uf1Xv73//+11599dWg69mwYYOrXKcw+/zzz7tlkydPdoUATjnlFOvXrx/vFgAgxxw5csQeeeQRq1evnl155ZVu2RNPPGEJCYFfoStXrux6brds2WKnnXZaWG0ARI7TQgBOiE2bNtnLL7/sgunpp5/ulv3+++82a9askAfxp556yvbs2WODBg1KW6Zwe/7559uzzz7LOwUAyFGa96rRREOGDElbljGkyi+//GIFCxa0cuXKhd0GQOQIswBOiEcffdSOHj0aMDdIPawajjxs2LCgz1mwYIGVKVPGTj755IDlF1xwgeu11TAvAABywqFDh9yxrEGDBta2bduQ7TSdZs6cOW76TLAQG24bANlHmAUQdWvXrrU33njDunfvHnT+USg6Y3348OFMy72z2H/++WdU9xMAgFA0JUYnUdP3yma0fft2u/nmm12dh8cff/y42wA4PoRZAFHnHfizW7FRPbAaZjxt2rSA5V6hDBXnAAAgJy7To2JNmuZy+eWXB22jyvvt27e3jRs32rhx44KevA2nDYDjxzgHAFG1YsUKV8GxV69erthFdvTt29c+/vhjdy2+e+65x/XI/vTTT/b++++7x5lnBADICapcrEJNY8aMCfq4ptF06dLF1YF47733ggbecNoAiAxhFkBUPfzww1agQAHr379/tp+r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AAAAAE7sdWanTp1qdevWtYIFC1qJEiXSll911VU2fvz4aGwCAAAAAIDohdmxY8e60HryySfbvffeG/BYp06d7M0334x0EwAAAAAARDfMPv/88/bSSy/ZV199ZSNGjAh47KKLLrJ58+ZFugkAAAAAAKIbZn/77Tfr2rVr0MdKlSplu3fvjnQTAAAAAABEN8yq2NOmTZuCPrZo0SI79dRTI90EAAAAAADRDbOtW7e23r1727Zt2wKW79y50+655x677LLLIt0EAAAAAADRvTTPY489Zo0bN7Zq1arZBRdc4Ja1bdvWZs+ebQkJCTZu3LhINwEAAAAAQHR7ZitUqGBz58617t2728qVK92leTS8WBWOtVyPAwAAAAAQUz2zcsopp7ihxk2aNLGtW7da+fLlrWXLlla2bNlorB4AAAAAgOiG2b/++su6detmn3/+ecDywoUL28CBA23AgAGRbgIAAAAAgOiG2T59+tivv/5qTz/9tDVo0MBdjmfLli325Zdfuvm0+vmOO+6IdDMAAAAAAEQvzKpH9uuvv7ZGjRqlLTv33HPt0ksvdfePPPIIYRYAAAAAEFsFoAoVKmS1atUK+piKQG3cuDHSTQAAAAAAEN0w26FDBxszZkzQx9asWWNnnHFGpJsAAAAAACCyYcYzZ87M1Pt63XXXWdGiRe2ss84KeOzRRx+1Fi1aZHcTAAAAAABEN8w2a9Ys6PJevXoFXT5t2jR78cUXs7sZAAAAAACiF2YnTJiQ3acAAAAAAJC7YbZjx47R3QMAAAAAAHL60jxHjx611157zT777DP7+++/LTU1Nct5tgAAAAAA5GqY7du3r73wwgtWrVo1K1WqlMXHR1wgOU1KSkqW64tWGwAAAACAf0Sc8N577z3773//a6tWrbJffvnF5s2bl+mWHerFveaaa6xs2bJWsGBBd9+tWzfbsGFDQLtPPvnEateubYULF7bExETr3r277dq1K9ttAAAAAAD5MMwWKFDAGjVqFJ29MbOHHnrINm/e7AJycnKyTZ482b744gu79NJLXQ+rfPfdd9apUye74YYbbP/+/S5EeyHYE04bAAAAAEA+DbO33nqrDR06NDp7Y2atWrWyr7/+2urXr++CcpMmTez666+3ZcuW2cqVK12b4cOH2xlnnGH333+/672tXr26DRo0yL766iubO3du2G0AAAAAAPl0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l1vHjh3tpptustdeey1tuU7MXnvtte6+QYMGubqPAHIGYRZAmtNPP931ypYuXdp+/fVXmzFjhl1wwQUBXwo0nGvy5MluONM///lPt+yHH36wxYsXu+edf/75Vrly5YBXNSUlxb755htbtWqVVapUybULl7Y3e/Zs27dvn3uu9qdEiRLusTPPPNMNM06/X8F07tzZhXRvXzTcWsOpy5Yt687kn3rqqXwKAMBHvbKHDx+26667LmB5lSpV7KuvvrI//vjDDfcVHcu8f7ds2dINRR49erT961//snPOOcc+//xzO3jwoF188cX2zjvv2CWXXGK1atVKW6d3LOzZs2fasUfHI4122rhxo1WsWNGaNGlixYsXt5dffjnoNtUmq3VLsP1SaF+4cKGtXLnSzYktVqyYOw7+4x//OOGvM+AHDDMGkEZhUEOkjh496oZq6WB81VVX2fbt293jR44cccFw5MiRVr16dXdgbdasmXXo0MHNW3rjjTfcF4WXXnopbZ1btmxxB3OdQf/xxx/tueees1atWoX1qg8dOtQFZh3UNWxMvcqaZ6v9kxdffNGefPJJ92/10GYcPj1s2DC777773BcCb66u1nfjjTe6gKznV61a1d5//30+BQDgE6VKlXL3P//8c6bHSpYs6YKejgGye/futGPCnj17bNeuXe44p///dSxSMNaxYfPmzW65jlPpKWxquZ4nn332mQvNDz74oNv+888/707gql2obYaz7lD7pXBer149d+xcsmSJ275GV91///0n7PUF/ISeWSCf0byi6dOnByxTcL3yyiszfVl4++23XRC97bbbbPz48fbwww+7g/d3333nim3oTLbOTC9YsCCt6MTjjz9u/fr1s8svv9ytV8WZNm3a5NooiMoHH3xgXbt2zXIY2aBBg9zZ7Ouvvz5t+SeffJJW3CO9mjVrpp0JFx3wdfBXIFZgTU1NtXbt2rme2UWLFqV9GVJAVvErnTFXTy0AILbpeKUwqZOVquTbpk0b1zvq/R9etGhRdzzQMUCFmNIfGzZs2ODu//zzT5s6darrURWNLsqKwmmnTp3c9nQcS0j4v6/RK1ascCdZQ20znHV7Mu6XjoU6+apRT55XXnnFHZd1HD3vvPPCXjeQFxFmgXxGwVLDs9LzDpoZabiTviyMGDHC7rrrLnvhhRds4MCBrjdWw540dFgHVS/Iyi233GIPPPCATZgwwS677DJ3dllnrr0gKyra4dm5c6crPJWeDtreXFgN21Lw1DJtp3379ln+jupJ1rCthg0bui88ogCuIV0fffRRWpD19vepp55y+9mjR48wXkEAQG465ZRTbObMme7E6VtvvWWvv/66W64qwjr+XHPNNVmuQydqQx37QtH8XB2bdNLWC7IZj2mRyrhf3nBi9faqZ1a9vF7RRoVowizyO8IskM8cqwBUMI888oh9+eWX7myz5ukozIqCoSxbtizgDLR3qR+d/fba1K5dO+T6Fay9oVnpD97e3CbNx/V6jdX7qp7WrAKtelo1ZEsBtkCBAgH7q0sUrV+/PmD76c/WAwBiny7rphE4e/fuddWM9f/9q6++6gpAaQSOpsREm07iahizRh3lFPXU3n777W4akOpG6DioY6w39QfI7wizAI6pYMGCdtppp7kQGB8fnzbE1wuBwS7SruFPCr779+9PG/IVinpbM4Zhj4ZWqedXc4YURpcuXeq+qGjYlYpVBaPh0Lo988wzAdew9fZXZ7VVvCO9//znP1S+BAAfUlGmCy+80N00JeXss8+2N99884SEWYVHL0jmFNV40Endjz/+OO3Erq4ry+V/gP9DmAVwTCpG8emnn7ovBuPGjXPDqzR01xtWpeJPugWjqsGiebXZpecoRD/00EPupjCq4WMKqfPnzw8aZlVsSr2yGh6tYdHpefvbrVu3HL2YPQAgujS8NtjQXlW41zQSr8q9TsCGyxvam5ycHLKNCh9OmzbNtm3bFrLGQrBthrPuYFTrQVWTu3TpkqmuBYD/QzVjACGpaIWGJWsuqYpdtG3b1hWBUi+tLs2j4cCqJux9cfBo2Jd6T+vXr+++WCgEe1QkY9SoUVm+6t9//70Lpt4wKvUQeyFUX1iC6dWrl9uXMWPGZCoSpYJUugSP5v9mHJqlyxHp0j4AgNink5qq55AxHOoEqqaYeAUGdUkcneQMhyoSaxSRRgB5dFxQrQiPV4xw+PDhAc/966+/0uaxBttmOOsORscxzQ9WePbo+PXEE0+E9TsB+QE9swCC0uVsdDZYc3Q0X9a7Bp7mv+rafgq0qix8xRVXuDk8mseqIk+6fuukSZPcc2644QZ3sNZlea6++mp3WRzN+wmn6IauC6vCHrp0gXp+FYJVKErhWtvLSIFZPcgtWrTIdL1Z7aPm32q/VNFYBTO0TBWZVVBDxZ90eZ5QQ5cBALFDQ4l1aRqdZNWxRycq1Vur44CmuaiKvuhErOos3H333S5QqhbDSSedFHSdqq+gUUA6YatjlE6gav3qAdZ1a6VRo0b29NNPu+OQjnU6qauiirpKgG66ZE+wbeqYk9W6j1W3QidqNapIJ3J1vKLyPvD/EWaBfEK9pJobeqyDoIbn6qyvhknpuq4XXXSRC6Je+NQZYh2AFRo1Z0dVjXVZBBXh0JxWVRHW9fD69+/vhmOJAq0CsAKmArLmxyog6wuBvpCEolCqa+zpebpYvM5qa86Qvkx4dDF5r+qxgql+P8lYUMqbu6vqxqtWrXJfBnR5HvXIam7vo48+6r6EAABi35133umOLboGuUKlekZ1zFGFY1U09ujybip4qPoLXu+mCjjpWKFjYkY6dumkq0YG6Zii66dr/aq/oOeJQqpOhuryOarBoMCq4lNeVeFg2wx33cH26+abb3YncL/44gs38khFrsqUKeNO0HqjlHQs1XN1jAbym7hUDcgHAAAAAMBHmDMLAAAAAPAdwiwAAAAAwHcIswAAAAAA3yHMAgAAAAB8hzALAAAAAPAdwiwAAAAAwHcIswAAAAAA3yHMAgAAAAB8hzALAAAAAPAdwiwAAAAAwHcIswAAAAAA3yHMAgAAAAB8hzALAAAAAPAdwiwAAAAAwPzm/wHPZu1A2AAqGwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 960x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved figure: saudi_labor_law_voice_agent_project\\05_reports\\figures\\08_chunks_count_by_strategy.png\n",
      "Interpretation: this quantifies how chunking strategy changes the retrieval search space.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Figure 8 - Chunking strategy comparison\n",
    "# =========================================================\n",
    "\n",
    "chunk_strategy_df = pd.concat([\n",
    "    df_structural_chunks.assign(strategy=\"Structural\"),\n",
    "    df_fixed_chunks.assign(strategy=\"Fixed-size\"),\n",
    "], ignore_index=True)\n",
    "\n",
    "chunk_strategy_summary = (\n",
    "    chunk_strategy_df\n",
    "    .groupby(\"strategy\")\n",
    "    .agg(\n",
    "        chunks_count=(\"chunk_id\", \"count\"),\n",
    "        parent_records=(\"parent_document_id\", \"nunique\"),\n",
    "        mean_words=(\"chunk_word_len\", \"mean\"),\n",
    "        median_words=(\"chunk_word_len\", \"median\"),\n",
    "        max_words=(\"chunk_word_len\", \"max\"),\n",
    "    )\n",
    "    .round(2)\n",
    "    .reset_index()\n",
    ")\n",
    "\n",
    "chunk_strategy_summary[\"chunks_per_parent_record\"] = (\n",
    "    chunk_strategy_summary[\"chunks_count\"] / chunk_strategy_summary[\"parent_records\"]\n",
    ").round(3)\n",
    "\n",
    "chunk_strategy_summary.to_csv(REPORTS_DIR / \"visual_08_chunking_strategy_summary.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "display(chunk_strategy_summary)\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(8, 4))\n",
    "ax.bar(chunk_strategy_summary[\"strategy\"], chunk_strategy_summary[\"chunks_count\"])\n",
    "add_bar_labels(ax, chunk_strategy_summary[\"chunks_count\"].values)\n",
    "ax.set_title(\"Number of Chunks by Chunking Strategy\")\n",
    "ax.set_ylabel(\"Number of chunks\")\n",
    "ax.grid(axis=\"y\", alpha=0.25)\n",
    "save_current_fig(\"08_chunks_count_by_strategy.png\")\n",
    "\n",
    "print(\"Interpretation: this quantifies how chunking strategy changes the retrieval search space.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "270aa364-02e0-464f-ad13-9c8dbd0d5629",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>eval_type</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>faq_retrieval</td>\n",
       "      <td>199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>legal_article_retrieval</td>\n",
       "      <td>24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>out_of_scope</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 eval_type  count\n",
       "0            faq_retrieval    199\n",
       "1  legal_article_retrieval     24\n",
       "2             out_of_scope     15"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA7MAAAHUCAYAAADocH+kAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAAaM1JREFUeJzt3QeUU+X3xvtNkd57BxHEQhOkiTRBRZAqoEgV8S8ioog/BUSKVAWlCChFBLGAoKCINBURxEKRLiAgVem9t9z1vPcmdzIFZpjMTDLz/ayVlcnJyTlnEuZwdt6995vM4/F4DAAAAACAEJI8oQ8AAAAAAICYIpgFAAAAAIQcglkAAAAAQMghmAUAAAAAhByCWQAAAABAyCGYBQAAAACEHIJZAAAAAEDIIZgFAAAAAIQcglkAAAAAQMghmAUAAAAAhByCWQAAAABAyCGYBQDc0PDhwy1ZsmQ2ZcoU3i0AABAUCGYBIESkTJnSBZTXu+3bt88Ss06dOrnfs1+/fgl2DJ988onfe546dWrLnj27VaxY0V5++WXbtGlTgh1bMLt27ZpNmzbNHnzwQcuZM6d73woWLGhNmza1r776yjwejyU1Mf33/Morr7j1dQ8AIJgFgJCSPHlyq1GjRpQ3BQihTqO/umDXaHAwy5cvn3vP7733XsuRI4etWbPGRowYYaVLl451sB2s78HNHtfJkyetdu3a1rZtW/v+++8tc+bMVqZMGTt37pzNnj3bHnvsMXv44Yfj7LhDyaxZsxL8CxsACBUpE/oAAADRlzZtWvvpp5+S7Fv2wQcfuFswaNKkiY0ZM8b3+NixYzZ58mTr06eP9e/f341Evvnmm5bUacT1iSeecP9uFcDqPSpXrpzv+Xnz5rkR7Z07d1pSE9N/z/oSIdi+4ACAhESaMQAAAZAtWzaX/rlkyRJLlSqVDRkyxNavX5/k39svv/zSFixY4FKKFdCGDWSlfv369scff1jNmjWT/HsFAIgZglkASERWrlzpUhTvv//+SJ9v1aqVe/6HH36wX375xR544AErUqSIpUuXzqUo6+fOnTvb4cOHb7ivLl26uG0pbTS8O+64wz3nFd19tW/f3p566in38//+9z9fXWrJkiWv24jqxIkTbv2iRYu6befJk8fatGlj27dv91tPqZt6/fTp092tQoUKliZNGhdoDRw4MCB1m5UqVbJu3brZlStXbPz48QF/D2LyuWl0eOrUqa6eN0uWLC4dukqVKu59OH78uG+9ixcv2tChQ90+NPqvdR999FGXOh3d44rK+++/7+41Yq3tRkZpx5MmTYrV56kRzuLFi7vjr1q1qu/YNfJbvnx5915pZFiPo9qGanrvuece37+JN954wy5fvuy3fnSPLTrvffh/z/qbat68uftZo/ve91ifr+h31OOwGQFy+vRp69Wrl/v9dUy5cuVyo+F//fWX33re/em9njNnjlWuXNm9X0qZ7927t129evW6nyUABBvSjAEgEVFwdtddd9mKFSts165dvotgUX3iN9984y7Sa9Wq5RoZHThwwKpXr+4uyL2BkoKPZcuWuWDglltuCchx7dixI1r7aty4sQsWvv76a9co6L777nPr6uI8KkrvVfCyZcsWN7qn9N9//vnHPv/8c5s7d64bKVWAElbfvn1t27ZtLiBRgPPnn3+6wEWjqwoKY0vBzVtvveXe77Fjxwb0PYjudkQjxarj1b+Jjh07uqB1/vz5LlAqW7as29eFCxfcfpYvX+62qdpVbV+1rD/++KNbrtHUm/lsLl265P4tij6X6IjN56l6ZR2P9lmvXj3r2rWrvf7663bbbbe5vwWNlGt7CvK0LKxXX33V9u7d6wJCfRmjRl76guPQoUO+LyVicmzRee/D0zFrfzNnznT12N7R6qi+BPAGstWqVbN169a5L7EaNmxoe/bscU21FLgvXLjQ91l5DRs2zL1fek/073/t2rU2aNAgy5Qpk3sfACBkeAAAISFFihQaNozy1q5dO7fe0KFD3ePBgwf7vX769Olu+euvv37d/TRo0MCtt3DhQt+yYcOGuWUfffSRb9nzzz/vli1evDjCNkqUKOGeu5HI9qV9aJn2GV5kx/HUU0+5ZW+99ZbfugsWLPAkT57cU7p0ad+yvn37unULFy7smT9/vm/5smXLPMmSJfMUL178hsc8bdo0tw39/lG5evWq+7y0zcuXLwf0PYjuds6cOeO55ZZb3O964cIFv2MbOXKkZ968ee5xz5493euGDBnit70//vjDvX916tS56ePavXu3Wz9fvnzR/j1u5vMsWLCgZ/ny5W7ZtWvXPI0bN3bLM2fO7Jk1a1aE9bt37x5hWdmyZT2//vqrb/n69es9WbNmdZ/h5s2bY3Rs0X3vI/v3PHPmTLdMxxXe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KtutW7frvoZgFgAAAACQoMFs5syZ7aOPPrLJkyfbwYMH3ejsP//8Y/Hl9OnTVq1atSifL126tH388cf23XffWa9evSJdp2fPnvb444/H4VECAAAAAIIqmPVKliyZ5cmTx/78808rUqSInTt3ztasWWNHjx61bNmyWfny5S1dunSBPVozt80pU6ZEWH7t2jVr0KCB7d+/3z0+duyYrVu3ziZOnGj33nuv37oFChQI+HEBAAAAAEIgmPUqW7asSz3u27evnTp1yrc8Y8aM9uabbwY8xThFihRun+F99tln9u+//9p7773nt7xYsWKRrg8AAAAASMLB7LRp0+yVV16xFi1aWO3atS1Hjhx2+PBh+/77791yPW7durXFpatXr1r//v2tTJky1qRJkzjdFwAAAAAgEQSz77zzjhuZ7dKli9/yjh07ujlp9XxcB7NTp061bdu22ezZs136c1jPP/+8pU2b1qU+P/LII+5xqlSp4vR4AAAAAABBHsz+9ddf1qpVq0if0/Q9r776qsWly5cv24ABA+yee+6xRo0a+ZZr+iDV84rSnxcvXmw9evSwhQsX2vz58yMEvV6HDh1yI8thbd++3d1fuXLF3YJNquSehD4EIMkKxnMCAABAUriuShmIhkxq+pQ1a9YIzykojIsmUGGpwdOuXbts1KhRfgGqjifsMVWvXt09r8B30aJF9vDDD0e6vXHjxrmU5ag6KZ84ccKCTaEMBLNAQgnGcwIAAEAoUrwVr8Gs6mRffPFF++STT/yCRwW4L7zwgj3wwAMWVy5cuGCDBw92nZMbNmx4w/WVZqxgVl2OowpmO3fubM2bN48wMtu4cWPX1CpLliwWbPaciXyUGUDcC8ZzAgAAQChSvBWvwayCySpVqljBggWtXLlyvgZQq1evdqOyv/76q8UVjaJqKp7x48dHa31NH+TtiByVXLlyuVtkUqZM6W7B5tI1glkgoQTjOQEAACApXFclj+0Ob7/9dhe4tmzZ0gWWP/74o5siR/Wymne2ePHiFhfOnj1rb731llWoUMHVx0bHqlWr3H3VqlXj5JgAAAAAAPEjIEMKRYoUcbWr8Uk1smrWNGXKlEifV+Opxx57zCpWrOhqZdevX28jRoxw6cKVK1eO12MFAAAAAARWSObHnTx50oYPH26VKlVydbCROXjwoNWqVculOquWd+/evdasWTMb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4MGD42oXAAAAAIAkKs6CWcmdO7frIgwAAAAAQFClGa9atSrCsmvXrtnRo0fddDmlSpWK7S4AAAAAAAhsMFuhQoUon8uXL5/Nnj07trsAAAAAACCwwey0adMiLEuePLkVKFDAypcvb+nTp4/tLgAAAAAACGww27p169huAgAAAACAuA9mmzVrFqP1Z82adTO7AQAAAAAgcMHs2rVrb7jOoUOH7PTp0zezeQAAAAAAAh/Mbt++Pcrndu/ebf3797ePP/7YcuXKZT179ryZXQAAAAAAEHc1s14HDx60QYMG2fjx4y1NmjTWt29f69atm2XIkCFQuwAAAAAAIDDB7PHjx23YsGE2evRou3r1qnXt2tV69Ohh2bNnj+2mAQAAAAAIbDB79uxZGzVqlAtkz5w5Yx06dLA+ffpY/vz5b3aTAAAAAADEXTCrUVilFB8+fNgef/xxGzBggBUrVuxmNgUAAAAAQPwEsy+++KKlTp3a3ZcpU8aWL1/ublFp3779zewGAAAAAIDAphlfvHjRRo4cGa11CWYBAAAAAAkezG7YsCGgBwEAAAAAQJwHsyVLlryZlwEAAAAAEBDJA7MZAAAAAABCaJ5ZAACQcPbv328rVqywS5cuWYkSJezee++97vqbNm2yZcuWWf369a1gwYLxdpwAAAQaI7MAAISoRx991AoVKmTjxo2zuXPnWq1ateyBBx6w06dPR7r+vn377MEHH7TnnnvOBbUAAIQyRmYBAAhR69evtx9++MFq1qzpHitALVu2rPXu3dtGjRrlt+7Zs2etQYMG7h4AgMSAkVkAAELU7NmzfYGs3H333Xb77bfbjz/+6Leex+Ox1q1b24kTJ2zYsGEJcKQAAAQewSwAACGqfPnyEZadPHnSBa9h9ejRw43gKhU5V65c8XiEAADEHYJZAAASieXLl7uGUBUrVvQtmzJlir3zzjs2ffp0ptYDACQqBLMAACQC6mbcpUsXS5Uqlb388stumboWP/vssy6YrVevXkIfIgAAAUUDKAAAEoFOnTrZunXrXOOnkiVLumU9e/Z00++kTp3aPvjgA7dM68h3333nAuCGDRsm6HEDAJDkglnVA23bts2OHDliRYoUsfz58/s9f+DAAdu4cWOkr73jjjusQIEC8XSkAADErYEDB9pHH31k3bt3t65du/qWK1DduXOnrV271rds165d7n7H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",
      "text/plain": [
       "<Figure size 960x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saved figure: saudi_labor_law_voice_agent_project\\05_reports\\figures\\10_evaluation_dataset_composition.png\n",
      "Interpretation: the evaluation set combines held-out FAQ questions, manual legal questions, and out-of-scope checks.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Figure 10 - Evaluation dataset composition\n",
    "# =========================================================\n",
    "\n",
    "eval_comp = (\n",
    "    df_eval[\"eval_type\"]\n",
    "    .value_counts()\n",
    "    .rename_axis(\"eval_type\")\n",
    "    .reset_index(name=\"count\")\n",
    ")\n",
    "\n",
    "eval_comp.to_csv(REPORTS_DIR / \"visual_10_evaluation_dataset_composition.csv\", index=False, encoding=\"utf-8-sig\")\n",
    "display(eval_comp)\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(8, 4))\n",
    "ax.bar(eval_comp[\"eval_type\"], eval_comp[\"count\"])\n",
    "add_bar_labels(ax, eval_comp[\"count\"].values)\n",
    "ax.set_title(\"Evaluation Dataset Composition\")\n",
    "ax.set_ylabel(\"Number of evaluation questions\")\n",
    "ax.tick_params(axis=\"x\", rotation=15)\n",
    "ax.grid(axis=\"y\", alpha=0.25)\n",
    "save_current_fig(\"10_evaluation_dataset_composition.png\")\n",
    "\n",
    "print(\"Interpretation: the evaluation set combines held-out FAQ questions, manual legal questions, and out-of-scope checks.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "44ceba13-a7d8-4249-b8e3-dc4f30e98c29",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>المرحلة</th>\n",
       "      <th>العدد</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>السجلات القانونية الخام</td>\n",
       "      <td>249</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>السجلات القانونية بعد التنظيف</td>\n",
       "      <td>249</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>المواد الفعالة داخل قاعدة الاسترجاع</td>\n",
       "      <td>211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>أرشيف المواد الملغاة</td>\n",
       "      <td>38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>الأسئلة الشائعة الخام</td>\n",
       "      <td>711</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>الأسئلة الشائعة بعد التنظيف</td>\n",
       "      <td>703</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>أسئلة الفهرسة</td>\n",
       "      <td>503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>أسئلة التقييم</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                               المرحلة  العدد\n",
       "0              السجلات القانونية الخام    249\n",
       "1        السجلات القانونية بعد التنظيف    249\n",
       "2  المواد الفعالة داخل قاعدة الاسترجاع    211\n",
       "3                 أرشيف المواد الملغاة     38\n",
       "4                الأسئلة الشائعة الخام    711\n",
       "5          الأسئلة الشائعة بعد التنظيف    703\n",
       "6                        أسئلة الفهرسة    503\n",
       "7                        أسئلة التقييم    200"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABZMAAALDCAYAAABgo56JAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAApcFJREFUeJzs3Qd4ZGX9PvxnYelFeu9d2tKlKkWRIh2li0gVBQQFEVGKICAISlFEpYgFRKlKURCkd6VX6aB0kA4Lea/7+b2Tfzab7EmyyW529/O5rtlkZ86cOS2TzH2+5/sMaWtraysAAAAAADAKE43qQQAAAAAAECYDAAAAANAjKpMBAAAAAGgkTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAAAAAGgkTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAMZxhxxySFlzzTXL3/72t7G9KOOMddZZp26zd955Z4LYjuPzuvV2P4+r3n///bouufXWhLj/+7rOY2pb3XTTTfV1DjjggDH6+t0dR4PxGGlraysXXHBB2WqrrQb9sgJMSITJAADjuPvuu6/84x//KM8//3yZkG299dY1YPjNb37TOG22V24ffvjhBLEdR7Vum2++eb3F0UcfXbfh448/XsbX/Tyu+uijj9rXp7fG52O7v9d5TG2rl19+ub7O3XffPUZfv7vjaLAdI5dccklZfvnl63vTXXfdNaiXFWBCI0wGAGC8sPDCC9eA4cgjjxzjr/25z32uhpxx+OGH17Dz2WefLeOCG2+8sd7iwQcfrNvwrbfeKoPV2NzPwMC67LLLykorrVQ23njj8s9//rMsueSS5ZhjjrHZAQYRYTIAAOOF3XffvUw88cQ1EP373/8+Rl/7+uuvLzfffHP9/v77769h57jSWuH888+vtzjwwAPL1VdfXeaff/4+zeupp56qQXoC9UjAvskmm4w3+xkYGFdeeWVZddVVywYbbFBuu+22ssQSS5Rzzz23Vm7393sIAKNHmAwAwHhhrrnmqtVs8dOf/nSMvvaf//zncs4559Tvv/e979VAds455yzjggQ4ucViiy1Ww+CpppqqT/N6++23a5CeQD0SsN9www3jzX4eX+XER/b7XnvtVf+fr/l/+uvCQPr3v/9d1l133fKZz3ym9pFOiJz30nvuuad84QtfKEOGDLEDAAYZYTIAAOONr371q/XrRRddVJ577rkx9rqrr756WXnllev3iy++eA3ipphiijKu+NOf/lQ23XTTWkl8+eWX93k+88wzTw3SE6hHQqHsi/FlP4+v0lM6JwHSViDyNf9Pf93xUQZ1y8/oX/7yl7G9KBO0nHRKX+QMpLfQQguV3//+97USOQPuCZEBBq+hY3sBAAD4fx544IFy5pln1gGG0rc2o9mvvfba7eEco7bOOuuURRddtDz00EPltNNOK4ceeqhN1iDH1ve///32/+fS8kMOOaRP227KKaesIV1LK2Dvb/Zz/8qJj5wE+NjHPlb/f9JJJ5XXX3+9TDrppGV8lH7mCcu33377sb0oE7QTTzyxHmfLLbdc7ds+2WSTje1FAqAHVCYDAAwSJ598cllqqaXKD3/4w1oxd80114zQMmCwyjImQDz77LPbL5f/+te/PtaWZ88996xff/GLX5Thw4ePkdf84IMPyg477FDXfYsttihvvvlmr/ot53k5adDTge8effTRcvDBB9d2D7lEPJeDH3TQQbXdRm96NWffHXHEEWWSSSYpP/rRj8qxxx5bKwIPO+yw0epH/MILL5RLL720nHLKKWX//fcv2267bR2ksNVXelzdz+Or9KDOMbjsssvW/+dr/j/RRGP34+Irr7xSl+OAAw6o/99ll13qiYTRtdlmm9XwfMMNN+yHpaSvvxtmnXXW+jXVyANxBQMAA0NlMgDAIHDttdeWvffeu1Yif/7zn69hx+yzz14fm2WWWcpg9uKLL9bQ4NOf/nT75fJj04477liD1bQ/SECRcHegJYxNSLLGGmvU0CS9ZvPaPQnj0iM0gXK2XQKuhK6j8uMf/7gGtN0FqDPOOGN56aWXerTcxx9/fD3mMvDefvvtV+9LVXyq44888sgacPdGLldPOH3dddfV+Xa2xx57lHF5PzNm5eco7yeTTz55/f/tt99e7r333tGeb/qZjys9zcdlTb8bvv3tb5dbb721ttZJi53HHnusvhcBMLgJkwEABoEMJJbwbdddd63tGfrrUu7tttuuBp0JpBNOr7jiimWttdbq14D6U5/6VA1B559//vbL5aebbroytuRS/ax3tmO265gKGYcOHVrmnnvu8vDDD9cK4W9+85s1rG0y/fTTl1VWWaUGyldcccUow+T0FN13333r9znpkGmzX3Op+IMPPljDmlS091QGvIpN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Sc/ASakUS/CYS5Tz3IR+HYOCzlr9THN5cwLNzh599NH2itCetBXINK3g4vLLLx/p8VaIkCCj8yXzuaw7Fl544VG+RgaHShuHhBgJSnMJ9YknnlhDkAwUN7parSm6GuiwFba1+g83afWmzTa56qqrRno8lc+tlg4JWtKypGMw9qMf/ai2wFhnnXVqxWDHwdR6coxkmvREzTRZnxyLqVzuiaxjKqrTPzWDdGUeqaDO/kklY3p1d/f6qVpuLestt9wywmOtStUcA33Zz52raAfDMdkf8v7QlfScjRwHHY1q/6dyPO1JcjIh7SmefvrpOoBgtmOq99MiZyD2WUe5EiNyTKddTG9kMMq0t5hyyinbT+D05Jjvy7bq6ftcT6ZpHUv9cby0eu439RjOsuQEYmTgwZ6ud04MtALr1nZraQX4eTwnlVoV36Pzu6HjSZnRvXoEgAHQBgDAWHXmmWfm03XbDDPM0Pbcc8/1+vn33ntvff7kk0/edu211470+GuvvdZ2/vnnt2233XZtU089dZ12kkkmqf//5z//2avXmnPOOevz11hjjbY33nij/f4HH3ywbZZZZqmP5XbkkUc2zuvyyy9vn37SSSdtu+KKK9ofe/TRR9vmm2++9sf32Wef9sd+97vf1fumn376trfffrvxdTbddNM6/ZJLLlm3Ub7fb7/9Rppuiy22qI+dffbZPdwabW3PPvtsXfY879BDD22//5FHHmlbdNFF6/3f/OY3e7QPW9s2t2WXXbbtrbfeGmm6999/v22jjTZqn2611Var+2LiiSduv2+55ZZr++Uvf9n27rvv9vgYiaeeeqrtgAMOqMfGRBNN1HbllVe29dZHH33U9sADD7TdcMMNbY899thIx/g000zTdscdd7Tf/8orr7StsMIK7cu+0EILtT3++OPt6/r5z3++3v+lL32pT/t5l112aRsyZEjbFFNM0Xb33XcPmmOyJdv4U5/6VNvXvva1xmnfeeedEfZ7tl1Hf/3rX+u+y+P33HPPCI817f9sm7nnnrt9/q11ueaaa0aatj/3WUdf/vKX6/Ny7O20005t119/fdvw4cO7nDbHdvbN5z73ufblOOaYY3q8zn3dVj15n+vJNDfddFPbVFNNVR/Pz8rovg9l/+U5eR+44IIL6s9hZ7feemvbhhtuWKfLz0TndetuvV988cW2ZZZZpn198jPw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d96yyCKLlIknnniUzxk+fHi59NJLy8wzz1xWWWWVkR5/7LHHykMPPVRmnHHGsvzyyzfODwAA6B8qkwEAGBAHHHBADYRXXHHFsv7665fFF1+8DBs2rNx6662jfN4+++xTNtlkk3LYYYeNcP8LL7xQPv/5z5cFF1ywbLDBBuUTn/hE/f7666+3BwEAYAwQJg9yb7/9dnnrrbdGez6ZR+bV3/MdE0ZnWQfLer/22mu1MmuwGCzbBYDx2x/+8IcaHv/+978vN9xwQznqqKNqRfGGG25Y3njjjS6fc+qpp5af/exnZciQISPc39bWVrbZZpty0UUXlcMPP7wGyL/85S/r77CNNtqoPPfcc2NorQAAYMIlTB7kdtttt1qZM7q22mqr8sUvfrHX833nnXfqh7T333+/2w99g3kb9HW9e+vdd9+tgXE+6Hb25ptvlumnn75++B0sxtR2AWDCdvTRR5d//OMfZeutty6rrrpqOfDAA8uuu+5aW15ce+21I01/9dVXl7322quGxZNOOukIj11xxRXl73//e338u9/9bllttdXKzjvvXIPq/A4+5ZRTxuCaAQDAhEmYzCh95zvfKd/85jfLH//4x/KpT31qUG2tBLippk3F7//+97+xuizXXHNNDYyznQCA/5MQubO0pWj9Hu/o3//+d9lyyy3LFltsUQ4++OCRnnfHHXfUr2usscYI96+zzjq1d/KVV15pswMAwAAzAN84LlWvk0wySZlssskGZP7HH398+/fbbrttr5773nvv1aB36qmnHpDnHHPMMeXhhx+uy7X33nvXD6Fjy3rrrVcHCDr00EPrh+CJJnKeBgC6cuedd9aviy22WPt9r7/+em1VscACC5Qzzjijy+e1KpVfeeWVkR6bc845yxNPPGGDAwDAAJN4jeM222yz8otf/GKMvd5HH33U496/6XeYQXJ6ozfPOeSQQ8pvf/vb2ndxIIPktPdIm4+0+0jbj+4kSL7//vvr5bYAwMjyezJX8WTgvCWWWKLe9+GHH9ZeyGlVceGFF5Ypppiiy03XukLq2GOPLf/973/b77/vvvtqwNxxLAAAAGBgCJPHQaneSQVv/O1vfytf+9rXBuy10s9wl112KSuttFKt+hk6dGj50Y9+1KPnfv3rXy+XXXZZl491F0iP6jndGT58eBlIuXw2H3zT7uNb3/pWt9Otu+66tR9kRp7PB+Pe7EcAmBCupkponKt3TjvttPb709IivZITJOdvje7kb5H0S37wwQfLvPPOWz7+8Y+X2WabrSy11FI1XO7NlVAAAEDfCJMHiZ5W+8ass85aJp988vKxj32sfPKTnywHHXRQue222/p9mQ444IDauzDtGy644ILyzDPPlGmnnbZX80hP446VQrfcckvtlZjl/9KXvtTlend+TndOPvnk2iNxyimnLJtvvnl59dVXy+jKAHqpjOq4XLfeemttpfHTn/60nHjiie33ZxnzwbijBMmPPPJI+fWvfz0o9mOWMduzP7zwwgu1+qvj7dFHH+2XeQMwfsvv1fxNkd8dv/vd78rSSy/d/thNN91U23VlMNhlllmm/Zargm688cb6ff5+iPwe/vOf/1wH3sv9X/7yl8vdd99dn9/qxQwAAAwcPZPHsgR9CVXPP//8GtRuv/325aijjhpldc10001Xg9MMOnfdddfVW56z+OKL1+rZF198sVbodOx33Fup+sllpGeeeWbZcccde7QeQ4YMqcFuR+kfnOU955xzaruITTfdtC5bKpzPOuussvDCC9dB/rp7TnduvvnmWp0U6RmdsDvbrCch7qikXUaWKYP4pCJ5VDKS/MUXX1zD45ZPf/rTZfXVV6+j0GdfZtkGYj/mA3ZabiSI7hiEp9o52yHbN/LBPPPoj0GJEqYnLAeA3l5BlIH48rvo7LPPri26OsrvzfxO7Oyee+6pLS/mm2++EVpfpL1Vbh1bZ+TvkFwdBAAADCxh8li2//771xYKCWITtqbaNoHgqELRVp/AVMW+/PLL5T//+U/55z//Wb7//e/XCp1IQD06nn322fo1l52mfUOqkn/5y1/W4LMrCYATYmZdupOWHFn2BL8JXddee+0aUKZ1RCv87E37jQTXWe/555+/bLfdduWqq64qoyvbM1Lx3CTTtKbvKIFrgujTTz+97L777u3bsnMV9ujsxxwfu+66aw2UU90czz//fJl99tnLJZdcUj73uc+V/rbnnnuO1M86lck5QQAAXUk7p1zdk99NGVOgq3ERjjjiiC6fm99vyy67bG1/MSo5ERtpoQEAAAwsbS7Goueee6786le/qsFjBo5JqLj33nuX3/zmN7UqNRKYPv7447XqtLOEt9NPP33517/+VX7yk5/UMDKh7B577FGrijvKvFujoPfEcsstV+ed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ADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhjZPAgAAffPhhx+We+65p7z00ktl3nnnLQsuuGCZaKKJGp9zxRVXlJlmmqmstNJKIz3+1FNPlYceeqjMOOOMZZlllmmcHwAA0D/85Q0AwIA46KCDyiyzzFKWXXbZ8pnPfKYsssgi9fvbb799lM/bd999y4Ybbli+973vjXB/AultttmmhtLrrrtuWX755ctCCy1UbrzxRnsQAADGAGHyKLz33nu1MmagfPDBB/XW3f8Z/e0yWLbxu+++Wz766KMyWAyW7QLA+O13v/td+fjHP17OPvvs8o9//KN8//vfL/fff38Nit98880un/OLX/yinHzyyV0+tu2225Y//vGPNWS+5ppryqmnnlreeOONstFGG5X//Oc/A7w2AACAMHkUZp111nLSSScN2FGy2Wab1eqalp122qmsv/76g+qoHD58eA0ZE6q///77Y2UZRme7jKltnO2UwLgr+bA8xRRTlPPPP78MFuPCsQfAuO/II48s1113Xdl+++3LJz/5yXLwwQeXXXbZpbzwwgs1XO4s9331q1+tYfFkk002wmN//etfy9/+9rfyta99rRx22GHlU5/6VNl9991rYP3KK6+UU045ZQyuGQAATJgmmDC5FYr21dgMU8emXGa655571g9quSx1MO7TVPyminxsuvzyy2tgfMEFF4zV5QCAwWS77bYrQ4YMGeG+tKWId955Z4T7H3vssbLllluWTTbZpBxyyCEjzavVGiOhdEdpnzHDDDOUK6+8cgDWAAAAmCDD5L322quGon2VyzNXXHHFMqFJZXYuN91hhx3KfffdN+ABfG+ek6qkfEj9y1/+UgfzGZs+97nP1eMjH37b2trG6rIAwGD2z3/+s35dbLHF2u9Lq4qNN964zD333OWss84aKYCOSSaZpH597bXXRnpszjnnLI8//viALjcAADABhck/+9nPaijaV1/60pfKXXfdNcppUh3buS9uWh8kXExA2t/9l1OVOzYqcnva+/eEE07odeuE3jwnfRf/8Ic/1D6JzzzzTBkorX2X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//xnt/Ps6XQAAACDNkz+4he/WNZdd90yLkmglsC4K2+++WaZZJJJaiVRb9avNb9WsDtQulqe1VZbrfzsZz8r++67b61UGh0///nPy2STTdavy9cXreCzKdxOhdcXvvCFfn/9MfVa49ryAtAz+VsiIfKf//znss0225T111+/hssrrrhiufbaa8t//vOf9mlvvvnmst1227X/7dGdnk4HAAAwOgzA10k+2OVD3kUXXVT6w5NPPlkmn3zy8vzzz5d55523XHDBBWVMyofLPffcs/zkJz8pv/3tb8v4YK+99iq77rprOfvss8sSSywxRl5zdKuyAaBlqqmmqiFyZ4sttlj9+tZbb41w8i8npXP72Mc+1u1G7Ol0AAAAY7Vncitkm3jiicuQIUPKuC4fxjJgzSGHHFK/H911SoDcqkx+5plnyvgsx8FEE0004MfBKaecMkJF7ZiQkwB77733eL8PARh77rrrrnoCep555rEbAACA8asyOS0PUkEz6aST1kre9OkbkwaydcShhx5aP9D98Y9/7NfWGU3Lmen6u/r16quvLvPNN18diOeggw4a0DYbn/rUp8oJJ5zQq+e8+uqrZVyw+eabD0iQPK6sPwAD6y9/+Uu5++67a8Vy/rYCAAAYb8Lk3/zmN2WPPfYoDz30UHtVcipSe6I/wtKXX365Vu78+9//rm0O0u6gP33uc5+rfQsTKvfHoGQ33HBDmXLKKcsGG2wwyvX/yle+UqfLwDydvfLKK+WrX/1qmXvuucvQoUNr1VJGgn/iiSdGuZ222GKL2mojo8UfddRRI1T19oeO63P99deX/fbbr1fPT9/eSy65pFfPueOOO8rXv/71svbaa5cFF1ywXi58zDHHlHFRX9YfgPFLTlbuvPPOZdZZZy1HH3302F4cAACA/g2Tzz///Nq+IaOFf/DBB7XqNqFlRhJvkuAvFTdzzjlnDVd/8IMflAceeKBXrz/jjDPW10yQ+OCDD452q4PWgG4dJUi+//77y+9///syuhZaaKEael9++eVln3326Xa6jTbaqLz//vt18J2Oso3XXHPN8tOf/rR+4EyA+/TTT5fTTjutHHHEEd3OL5XVr7/+eq1OzmA+Sy65ZO2d3J9Gd3+eddZZNeQ+/PDDezT9YYcdVj7zmc+U+eefvw4seO+999bK+L5WXGegomzbqaeeup6gWHrppesH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AAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGg21jYDRdfHXVi/Dhg2zIel3w4cPL6+99lqZbrrpytChfmXhGAMAABibVCYDAAAAANBImAwAAAAAQCNhMgAAAAAAjYTJAAAAAAA0EiYDAAAAANBImAwAAAAAQCNhMgAAAAAAjYTJAAAAAAA0EiYDAAAAANBImAwAAAAAQCNhMgAAAAAAjYTJAAAAAAA0EiYDAAAAANBoaPMkAKO28cnXlyEzPjNeb6Ynjt5wbC8CAAAAwFilMhkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTYQL34Ycfli996UtlkUUWKffee+/YXpzxbtvef//95eabby5PPvnkKKd9+eWXy2233VYef/zx+jwAAACAwUaYDBO45557rjz99NPlz3/+c1l44YXH9uKMFz766KPyla98pcw000xliSWWKKusskqZb775ypJLLlmuuuqqEaZ95plnymabbVanXWmllcoCCyxQFlxwwXLBBReMteUHAAAA6IowGSZwd999d7n++uvLqquuWn7/+9+P7cUZL7z//vvl1FNPLcOGDSunn356ueyyy8rhhx9eHnnkkbLpppuWV155pU6XCuT111+/XH311eXSSy8tb731Vq0On2222cqWW25Zbr311rG9KgAAAADthv6/b4EJ0ac+9aly33331e9nnnnmsb0444WJJpqonHbaaWXXXXdtv2+99dYrL774YjnppJPKv/71r7L22muX22+/vYbH3/zmN2uoHKlk/vGPf1yrmf/4xz/WamUAAACAwUCYDBO4qaeeuiy00EJjezHGK5NOOukIQXLL888/X4YOHdreTmTIkCH1a0LmjiabbLL6dZppphkjywsAAADQE9pcTMBSDbnjjjv2+nlf/vKXy1577dXn191tt91GeH5fl6Oj/pjHmFzewWZ8XKfB1Ebk/PPPr4McptL4uOOOK3PPPXd9bPnlly9LL710+fWvf10OPvjg8sYbb9T7zzjjjBokf/GLXxzLSw8AAADw/wiTx2PPPvtsrTh96aWX6iXzl19++QiP//e//63T9GXAtv/85z99Xq7Oz+/rcnTUH/MYk8s72IyP6zRYHHDAAWWLLbYov/3tb8uPfvSjss8++7Q/NvHEE5e//vWvtV/1kUceWeaaa67y2c9+tobO6aE877zzjtVlBwAAAOhImDwem3XWWWuAPP3009eB1dZYY42xvUh0cNBBB5Vvfetb/bpNFltssXLLLbfYzoPID3/4w3LJJZeUAw88sN422WST0tbW1v74X/7yl1q9nKB5hx12qPsv7TD+8Ic/1AH6AAAAAAYLPZPHY+nN2uqFO9988/XquSeeeGK54447yllnnVUGi+HDh9d1Gl/su+++I4SK/SHB5BxzzFEGwgsvvDBSb99HH310QF5rfJI2Frl97nOfK1NMMUX5zne+U84555yyzTbblLvuuqv2Vs5Jhf32269O/4Mf/KDsvvvudaC+aaedthxxxBFjexUAAAAAKpXJ47lrrrmmDvbV8dL6nth+++3LUUcdVQaTLbfcstxzzz1lfDHzzDOXWWaZpV/m9a9//aueOMhJg1122aX8/Oc/L/3tpz/9aVlyySVHuG266ab9/jrjs/RIbu2vSDuLjz76qGy88cbt0yRATs/kKaecspx33nljbVkBAAAAOhMmj+dWXnnl2uYilcbHH3984/QJufbYY4+y7rrrlvXXX7984QtfKBdeeGEZDL73ve+VrbbaqlZ19qQHcKZdbrnlysknn1wGm7Qd+eQnP1lbj5x77rmjPb+Pf/zjtaVJevCmrULWvb/tueee5d577x3hNliOjcHmtdde6/L+xx57rH6dccYZ69d33323fv3f//43wnSTTz55mXTSSbW5AAAAAAYVYfJ47OGHH65h6nvvvVcrSPfff/9yxRVXdDv93//+97LSSivVqta0uEgf11RGbrbZZjWg7MlAdTvuuGMZNmxY2Xzzzcudd97Zr+uTdckyHn300eUnP/lJt9Olz2zC8PSc/ec//1n22muvcvbZZ4+x5U1gmCrhtDDoSgZc23bbbct1111Xrr/++rL11luXyy67bLRec7LJJmtvaTLnnHOW6aabrn6f9glZx/6QKuolllhihFvrNRlRKo5zIubxxx9vv++hhx6q1f4J/PMzFeuss079+uMf/7i2cWm5+OKLayCd1hgAAAAAg4UweTyVYGrDDTcsK664YrnttttqsJoq2LRA+OCDD7p8TsKuOPPMM2uQfP/999cevPPOO2+PeuNuscUW5de//nV97gUXXFBfr7/bUsw222w1jE34lsCuK3/729/q66aSOYHtPPPM02UYPlDLm8HT/v3vf3fb3zn7ItXiqSS++uqra/h7+umnjzDNl7/85RqCdychf9qXdNyXL730Ug13M8+Oy/Lss8+O9jrR+3A/+2jBBRcsSy21VFl22WXr12eeeaZeJZB9F+utt17tj5yTCWmB8c1vfrOeaMix+YlPfKIcfvjhNj0AAAAwaAiTx1P33XdfDYAzyFsul59kkknKscceW8OstCeI3J8AsuVLX/pSWWaZZcoDDzxQFl100do6IY8nGEsw27HyN9XOHWW+N998c+3NnPmff/75Zaqppio77bTTSOF1npvqzNGpkD3yyCPL3nvv3WUbgKeffrp+TSX26quvXr797W/XZepYJTqQy5uet5H5d2WGGWaoAfLaa69dPvWpT5XFFlusvd1Bx6ry3Lrz6quv1v375JNPjnBfQuyOLRbefPPNuv86SxsMVa8DZ4cddqgnMnIMpo91jtkMtJdjIu1COjr11FNrxX0q71PNnhNBP/vZz+rzW8cSAAAAwGAgTB5PtdocnHbaaTVwza3V3zZVsTH//PPX8Co9hZ944okyxRRTlEsvvbQGW0svvXRZc801y2GHHVYvuZ9rrrnaw8lU76Y9Q4LLllQwxzTTTFND6E022aSsuuqqtV1GgrW33nqrPv7666/XdhJzzz13n9ctA5alfcV//vOfLnvTJpyN3XbbrbaySHV2x5B5oJc388v2+vrXv14rqFMd3FFaTyScTuXpWmutVa666qpaidyS10s1+bXXXlurpruS9Y+E6tm3bW1t5ZRTTqn3ZR9GKpIzAGMqyzvbb7/96jbIazAwciLjmGOOKZdcckltL5P9kzYyXclxkEH3UlWfyvVcQZATQAAAAACDyZC2pFCMlxKO3nTTTTVYzm5OMJrK44SVQ4YMqVWtqUBuVRkvsMACZaKJJqphbWugsFTQTjnllPW5q6yySq3ibYXIaeOQeafytWMrhYTVqe5N8Jz5p31GBhRLG4lU06ZCOCFnqnJj++23rwPmXXnllV2uRwLejgPKvfzyyzVEXnLJJdvbUnScR9Y1gwe2+kNneVK1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/AfSgw8+WO69996ywQYblCmnnHKEx/LG8/nPf76cd955Zcsttxzw7QoAAAAwoTv88MNrK9LDDjtshPuHDh1abx1bX3Slp9MNJJXJDIhUut5yyy3l8ccf7/MAcDlT8/Wvf320B5B7//33a3j7xhtvlMG8vgNhq622KieeeOLYXgwAAACACdqjjz5aB8zbYostyrBhw8q4SmXyBOrqq68uc845Z1lkkUUGZP677bZb+/drrrlmnweQW3LJJcvKK69cA+G+nnXJGZ9zzjmnDkQ3zTTTlMG4vqkgfuihh8rGG29cJplkkn5ZpsUWW6xss8025dhjjy177rlnmXbaaftlvgAAAAD0fkC+jz76qBx66KFlXKYyeQL1t7/9rYaXA+1///tfueeee+rrPfLII7167kQTTVTefvvtOoBcAuG+eO6558o111xTK5MT2D755JNlsK3vnXfeWUPk3//+9+WDDz7o1+X53ve+V15//fXaU2d0vfDCC+W+++4b4ZazagAAAAB0L5lUCh233nrrssQSS5RxmcrkCcgFF1xQq3tnmWWWcvDBB4/UR7e/JAA++uijy9lnn137D88zzzy1Ejp9YQ488MARpn355Zdrv+GEqIsuumhZYIEF2h/rPG1fZIC5rPdGG21U209k/eedd94ytta3uwrsLFOWMWF0f+6XVJ6nOvn4448ve+21V5l++un7PK+f/vSnI/X0AQAAAGDUksMNGTKkVieP64TJ47CEmNdff32ZYYYZyjLLLFMbcI9KQsVWhe/EE09clltuubLZZpuVbbfdtj1g/c9//lNmn332Pi9TyvUzWF4Go0ugOt9889X7p5tuuhGme/PNN8tXvvKVWo2baVs+8YlPlN/+9rdlwQUXrP/P+qXtQ+7vixVXXLHeIoPMdexxnIH91lhjjTI6erq+o5LK4RlnnLFccsklta3HbLPN1ufluf322+vgeh3XK9XJ2c4/+tGP6gCAfZVWGRm0r6NUJm+66aZ9nicAAADA+OzWW28tF110Udlxxx0HrN3smCRMHkclxEtv3lTeRkLItIMY1UG5+eab1+Ay1cC5PfDAAzVUTdj4hS98obz44ou1j3KagffVzTffXG644YZaut8KVocPH15D145+9atfld/85jf19dJ0PEF4Bq/LIHY5S5PHIuFngtnMryeeeOKJcscdd9Rm5i0J0BPUrr76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BgAAAACgkTAZAAAAAIBGwmQAAAAAABoNbZ4EYNQ2Pvn6MmTGZ2wm+t2kE7WVeaZuK0+9OaS8/9EQWxjHGOMc72M4xhjXeR/Dccb4+l72xNEbju3FGiepTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAAAAAGgkTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAAAAAGgkTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAAAAAGgkTAYAAAAAoJEwGQAAAACARsJkAAAAAAAaCZMBAAAAAGgkTAYAAAAAoJEwGQAAAACARkObJwHGVTfddFN56623yqc//emxvSgAAAAA46x77rmnfPjhh90+Pu+885bpp5++/f9tbW3lySefLMOHD6+PTTLJJF0+7+233y5PPfVUmXrqqcvss89eJp544jKYqUyG8dTpp59edt999/KnP/1pbC8KAAAAwDhtjTXWKMsuu2y3t7/85S/t01555ZVlwQUXLPPPP39ZeOGFa0j8q1/9aoT5XXPNNWXNNdcsH/vYx8rHP/7xMvfcc5dZZ521HH744eWjjz4qg5XKZBhPvfTSS/XNbO211y7vvfdemWyyycb2IgEAAACMk37729+WDz74YKT7r7vuunL88ce3Vx7/+9//LhtvvHGtUj755JNrxfGJJ55Ydt1111qh3Lp6/Jxzzil33nln+cpXvlI+8YlPlNdee61Of8ghh9Tn7rXXXmUwEibDeCqXXrz++uv1ze4zn/mMMBkAAACgjzbccMMu7z/qqKPKTDPN1P74SSedVN55553yt7/9ray22mrtz02QnGlbYXIC5IMPPrjMNddc7fNKfrPooovW5wqTJyApa19sscVqOftAuPnmm2v/lBVXXLH+/4477qiVp6uuumoZ3w30ug70tk0P46FDh7bPfyB9+9vfHmXQfMkll5SVVlqpzDHHHBPUMQQAAADQHy688MJy6623lmOPPbZWILdaXKRdRStIjoTNn/zkJ+tjCZqnmGKKstNOO400vzfffLN+XWihhQbtDtIzeQBst912NagbKEcccUQ55phj2v9/wgknlO9973tlMLnrrrtqqX4aiOcHpa9uvPHGctVVV42xde3rtu3p+h522GEjzH8gPfzww/VNLY3cO8sb12abbVa372A9hgAAAAAGq48++qh897vfrcHxnnvu2T7o3qOPPlrmm2++kaZP0WkG43vsscdGuP+NN94ot9xySx37asstt6wFqqMqEBzbhMkN/vWvf9WQsK8yamPHMHRCkQrc66+/vv4A9XUAuNNOO632jbngggtGa1nef//9Gqq2zu4M1vXtb6k+3mKLLWq/HQAAAAD6z+9+97ty77331uB3yimnrPe99dZb9crvVpVyRxloL15++eUR7r/hhhvKyiuvXHbeeecyzzzzlKuvvrrMPPPMg3ZX6ZncIDs0odxyyy3Xpw38yCOP1CBznXXWKROSPfbYo/37DADX1wHkst0/9alP1UB40kkn7dN88kN85pln1tYSXf0wD4b1feCBB2ol8QYbbNDesH10ZSTQrbbaqvzwhz+sofw000zTL/MFAAAAmJANHz68HHrooWXOOecsu+++e/v9rQH6JptsspGek7aqkYyro2Rf5513Xr3aPYWV+X96Ji+xxBJlMFKZ3OCrX/1q2Xvvvfu8gdNUu6kyNC0xXnzxxZEqaXM2Iy0TcjD1d1/gyy67rIwJWYcEpTmrktEseyOXBrz66qt1ALkEwn3xn//8p1YMZ3s++OCD/b4t+2N9U/2+/vrrlzPOOGOkN5TRldYV2YY/+clPRnteL7zwQrnvvvtGuKUSGwAAAGBC8qtf/armPgcddFCZfPLJ2+9PL+SOoXJHrWyrVcXcMssss9T2Fvvtt1+55ppranFligIHK2Fyw1mGNNFO35J8PzoB4z/+8Y9y//3314C0s7PPPruGnp0radMzJS0T+juwu/TSS2sFbMfXbHnttdfqgZszIH0NXt99991y+OGHl4UXXrgsu+yy5Wtf+1pZd91161mW3rzed77znRoC59bXqtrM8/e//339Pu0yBiL87M36diVvEumb8/nPf77fW3Gkz87WW29dfvSjH9VtPTp++tOfliWXXHKE26abbtpvywoAAAAw2L377rt1zK20pNhll11GeCzB8gwzzFCzns5ahaRzzDFHt/OebbbZygILLFDzyMFqgg2TMwBZQsqudm4k1Muoi5/4xCdq35KMuJhwt7d+/etfl/nnn7+sueaatTw9IWPnUO8Pf/hDWXrppdv/n+A0y5YD6Gc/+1mf20R0Z6ONNqpfOw4Ul8A7o0imJ8taa61Vl3Peeectq6++enn88cdH6A18++23dzvvhOWf/exny1/+8pdy+eWX19YN6Rk91VRTjTBdf71ek+y/7INIhXhrW95xxx3tg8+Njp6u76ikcjj7POHz008/PVrLk/7endcr1ck5do8//vjRmneayacXUMdbjlMAAACACcVPf/rT8swzz9TB97pqybrMMsuUe+65Z6SCwVyZnqA5IXS8/fbbIz03rXZT/NnqrzwYTbBhcloRbLbZZl1W50baAuQswFJLLVWWX375Gmqm92xHue+2227r9jXSgHvHHXcs//vf/2qIucgii9QAd//99+/RfJrm31crrLBCmX322Ws1cMfy/FRDzzTTTDXYTeVyeu6mZ3TCyJbDDjusHHfccaNsoXHttdfW0vxU27Z+EDLCZUf99XpdDXh40UUXjXBfKr0Tej7//PPt951wwgkjvE5f9XR9RyUVyd/61rdqJXb2zeis14knnjjSei266KJlm222KT/+8Y/bm7x3VSHfJJdd5IRIx9tCCy3U6/kAAAAAjIvefPPNcvTRR9fq4S996UtdTrPFFlvUDgcnnXRS+33J4P75z3/WLHKiif4vjk0Ra8dCz2RJCaiTI2a6wWqCHYCv1buku7YCDz30UG1ZkArWIUOG1OrTtLvoKI22M6BbWlF0lobZCawTIic4nW+++epBsd1225WLL764/OIXv2icz6jmPzqyPglvU02bUDH/T2CeUvysb6vcPtsoZ1NSLdySdcj03WmFqKmCzfc5U9Nq2dExwByd10tY250rrriiNj5//fXXy7TTTlvvS4CaH8L0pv7c5z43wnKOrp6ub5OmfZ03nV133bVH69XV/knAnHYfxx57bH3Tu+uuu7ptCA8AAADAyE444YTariL5ytChXceqX/7yl2sWmH7KabmavOe6666rRXqHHHJI+3SPPfZY+cxnPlOLE1Os98gjj9T7Fl988XLkkUcO2s0/wVYmp/VEQrdUa3bVFDutILITE06mOvjuu++uPXFbEhSm/24GdetKguSEmn/9619rkBw585BK55xhaAWN3c1nVPP/73//2+cewi2rrrpqnU9aM7TOhqTyesUVVyznn39+bS3Rau/RGpUyQWW2SaqJu5PK2hz0qeredtttywEHHFCeeOKJMskkk4zQr7ivr5fLAdJeIW0yupI2E5EK55bWNswAch0rfbvqCd3bbdvT9W3Jvk/g3FHTsdTx0oem9UqLkBlnnHGk5+fYzYmMnBXLZRUZWDLS9xgAAACAUcsV4ldddVUNgLfffvtup0vxZMZOS3CcAfnyvD322KMWVM4999zt0yWf+f73v1+vKE/BYKqdUwCYq+C7ynYGiwm2MjlnAzbffPParzhBYEZNTCiYniQJfXNL24X111+/Tp+dmAA07S9SzZm+tDlbEOn9O2zYsBoap/9tgr88d7311qttCFL9nHYaCQIz+F0CvFNOOaW2mkjrgs7zyYHV+f7Ma5111qlVqDn4vvCFL/R4XRMwtipRI2dQ0j84Eipm/nnN9GxZY401ajl+5Pu8bgL36aefvv7AJChN9XB3sm3S9iHPSRCcPsh5ja222qoONJj/57Uyv768XnogJxDN12zHtIiYeOKJayCbkDnbNdIAPW1G8kObH8Q46qijash73333tfcVztmibNe8EaRSu7fbtifru8oqq5TllluuXHbZZbW6PSH53nvvXd8kutrXrWOpYwB96qmnNq5X1v/666+vb0Qdq7hzzLQG48uxmYr7yMB8OakCAAAAQHMGdM011/RoM6UaOVeh59adZDIHH3zwOLfZh7T1pXnqeCIhXao1//znP49yugTLXbVFSKuGhHOpQu5ump7Ms7v5dHd/Quj777+/TDfddPX/ORuSitqOfVY6SnC81157jXBfAti0k8iZks4y8F/C84SunSWQzJmT3rZHuPrqq2swn7MxmX+Wty+vl3A0LTpS8d2VzCeDHXZuF5GG6O+//377/xNWpzL9lVdeGWG63m7b3q7vlFNOWfvmZFl6sq9b0gok1eR//OMfR7leOUmS5W+dwcqJjK4qrXMiJWF3lmd01jP7LKH+PLucXIbM+P8CcOgvk07UVuaZuq089eaQ8v5H3bfYAccYg5X3MRxjjOu8j+E4Y3x9L3vi6A3H9mINCq1sJ0WKGR+ryQRbmRzpPZuqzTTATjiZPskJmBP2JYBLv5JULKdaORXM2bh33nlnmWqqqWp7hvQ+SbiZytBUHc8111xdvk5Cy8wjA82lYvnnP/95beuQqtRUoHaeT3f354xFwtUEw62ws9VqIRXR3UkF7CabbNK+LAkcd95557LSSivV3s6//OUv6zrNPPPMZemll67zz//POOOMGoomnEyYmQrbVNT2pc/uWmutVduF/OxnP6vVxglBc+vt6yUET2uOTJf+MwlLs065Zbvtu+++ddulP3BalCRoTbic8DR9qjPvVESnSXqek0rzbNtso1Sm93bb9nR9sw5Zvrxuluk3v/lNvWyhu33dOpayjFneb3zjG3XaUa1XqqC/9rWvjXApRPr3tPZ9qpdzDG266aY1mO6or+sJAAAAwIRjgq5MBkaPymQGmkoYHGOM67yP4RhjXOd9DMcZ4wOVyd1TmTwG3HTTTbVNQqRNQucqz/F5vVO1m+pqAAAAAGDCMkG3ueirv/3tb2WRRRap36fH7YQSJme90/pDmAwAAAAAEx5hch9873vfKxOiCXW9AQAAAIBSJrIRAAAAAABoIkwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGgmTAQAAAABoJEwGAAAAAKCRMBkAAAAAgEbCZAAAAAAAGg1tngRg1C7+2upl2LBhNhP9bvjw4eW1114r0003XRk61K8sHGOMe7yP4RhjXOd9DMcZ4wPvZf1HZTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2GNk8CMGobn3x9GTLjMzYT/W7SidrKPFO3lafeHFLe/2iILYxjjHGO9zEcY4yv72NPHL3hWF0uAMYOlckAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0EiYDAAAAABAI2EyAAAAAACNhMkAAAAAADQSJgMAAAAA0Gho8yTA+Kytra3sv//+5cYbbyynn356WWyxxcb2IgEAAOOZF198sTz//PNdPjbttNOWeeaZZ4T73n///fL000+Xqaaaqsw222zdzvfVV18tL730UpllllnKxz72sX5fbgBGpDIZJnBPPfVUuf3228txxx1X5p577rG9OAAAwHjo5z//eVlqqaW6vO25554jTHvMMcfUcHihhRYqs88+e1luueXK3XffPcI0J510UllyySXLDDPMUBZZZJEy3XTTlWWXXbZceumlY3jNACYsKpNhAvfII4+UW2+9tXz5y18uhx12WNlqq63G9iIBAADjqR/84Adl4YUXHuG+BMYtv/rVr8qBBx5YVltttbLrrrvWauajjjqqrLfeeuXBBx+sVcytwHmSSSapn2EWXHDB+tjxxx9fNt1003LfffeN9BoA9A9hMkzgcvb+73//e/1+vvnmG9uLAwAAjMfWWmutsvLKK3f7eELitLX461//Wqaccsp637zzzlu23nrrcsYZZ5R99tmn3pdq5v32269MPvnk7c9Nm4u08Lv66quFyQADRJsLmMDNOOOM9Y+53EbViwwAAGAgPfnkk/XKyQ022KA9SI5NNtmkTDzxxOXyyy9vv++ggw4aIUiOd999t35dYIEF7CiAAaIyGfrgm9/8Zpl00knrJVpx6KGHlldeeaWceOKJ/bI999133zLFFFO0z3+g9ffyAwAAdOW5554rDzzwQO1x3LG9RTz00EP16/zzzz/C/QmN55xzztrKorP//Oc/5fHHHy/XXHNNOeKII8p2221XPv3pT9v4AANEmMwY8cMf/rC89957deCEM888s5x33nnj9JbPHzEdz4I/+uij5b///W+/bYf8cTX11FOXMaWnyw8AADA6tthii/bvU0GcPsepPI4UuERXn4USPic07uzII48sp5xySnvRTz5zATBwhMmMEZ///OfLRx99VAdLyBnlwS49to477rjyl7/8ZYLeDgAAAP0hfY/T43jRRRctk002WbnrrrvKaaedVjbffPPyj3/8o6y++urlgw8+qNPm8c7S5uL9998f6f5ddtmlfOITnyh33313OfXUU8u//vWv+jkuV5IC0P+EyYwRHS9TmnnmmQf9Vh82bFj5/ve/P6i2wzvvvFO++tWv1qrlv/3tb2O0cjleeOGF8uKLL45U0QwAANBkhx12qLeO1lhjjRom//znP69hclr9xfDhw0d6fq7w7NhHuWWZZZapt1hiiSXKTjvtVNv3pUoZgP4nTGaMePvtt8ull15azxZnUIW0VMgfEttvv/2g3AMzzDBDvQ2m7XDjjTfWASVOOOGE9j+yxqSf/vSn5bDDDhvjrwsAAIyfPvOZz9SvTz31VP06xxxz1K+di1ha97Ue704C6bj55psHYGkBiIlsBgZaLjGab775yrnnnlsvbUpwmmD0mWeeGeMb/3//+18d3G7dddctJ598cpfT5LKobbfdtqy//vr1squ2trZBsR0SPv/pT38qu+6661j542jPPfcs99577wi3Cy+8cIwvBwAAMO7JlZZdDZ7X8arNJZdcsgwdOrTcdNNNI02XMDlXkEaKbLry7LPP1q9pKwjAwFCZzIC3Rkif4IMOOqgcfPDBI/S76g9pRZE/KnIZU0/kEqqrrrqqfp9WETPOOGPZZptt2h9/+umn66VWb775Zv3/5ZdfXl5++eXy7W9/e6xvh89+9rO1l1gstthiY3S7xSyzzFJvAAAAvZG2FelrnKsdW9XDaVvxne98p37fulIzIfA666xT/v73v9eeyq3w+Nhjj61ft9xyy/o1xTX5LPPjH/+4zDPPPPW+119/vXzve9+r32+66aZ2EMAAUZnMgEqVb85ATzXVVPX/GXzuggsu6PKsdEcXX3xxWWWVVcqHH37Yfl9G9l155ZXLDTfc0H7fv//973L//ff3uLI3QfLWW29dg+T0L77kkktGmCbLllYU+cPksssuK0svvXT55S9/WcbWdugoA/alqjnbJiMZj6ntBgAAMDqGDBlS7rnnnlq4s/jii5cNN9ywLLTQQuW8886rxT0dw99jjjmmTDLJJPVzTa4WXWGFFWqrv4TMrekmmmii+nlqgQUWKKuuumpZb731yoILLliuvfba8qUvfalsvPHGdhjAABEmM6AWXnjh+os+gx/krPKss85aq4MzCm93lybF888/X882p1K45dVXXy233HLLCP2zEvzmD43Odtttt/pHSccWFa0+XD/84Q/rHyLpt9X58qeEvRnUYauttqp/kKy22mpd9ifOKMNZr4HaDgmbWyMZd3THHXfUYHqgthsAAEB/yxWZCZPzeSgt/zJ2zLLLLlvOOuus8pvf/GaEafN56dZbby1f+MIXyksvvVQ/ox111FG1bWBC6fjkJz9ZC4X22GOPOu9cCZrPbpnX6aefbgcCDCBhMgMq1b8Jb/MLPoPOpUp25513LrPNNlvtt9tdZe6DDz5Yv+aypZazzz67fs3Z5lZIev3117df1tTRdtttV84555wRnt+q1s0fMRtttFENWBM6d5TLq1ZaaaWy1FJLlbXWWquceeaZ5fjjjx9hmixzAt1UCg/EdsjlXqkaTp+whMMtjzzySLn99tvLddddVx577LEB2W4AAAADIf2Q064iV4CmSCZXVX7xi1/s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+YqP9FlOb+QHHnigV9MBAAAMBtpcQB/cd999I1SlJQz473//2/i84447rrz//vtl2WWXLWeddVY555xzupzu3nvvLVNPPfUY2zc9XX4ARvbMM8+UP/7xj2WJJZYoSy21VL3v5Zdfrl+7ei/PAHutCuaeTgcAADAYCJOZYJ166qnlqaeeKuuvv3455phjyp///OcBf80M0vTRRx+Vj33sY7XiDIBx2/Dhw8sXv/jFOlDeySef3H7/Bx98UL92bocRQ4cOrScWezMdAADAYCBMZoKVEPntt98us8466xhrKbHgggu2f9/bMDmDO+299971kuf00ByTlcvxwgsvlBdffHGE+x599NExugwAg83uu+9err766vLjH/+4rLnmmu33t/ofJ2zu7L333mt/vKfTAQAADAbCZCZY8847b/v3n/jEJ0Z47PXXXy8bbrhhOffcc8s3vvGNsuOOO9bweXSlcu2KK64od999d3nyySdra4ntttuubLvtto3PveGGG8obb7xRjjrqqLESLvz0pz8thx122Bh/XYDBar/99iunn356OfLII8s+++wzwmOzzz57/dpVm4qcmFtooYV6NR0AAMBgYAA+Jlj33HNPvTR5o402qmFAR1NNNVU5+uijy4wzzlj233//svzyy4/2611++eVl/vnnr72SUw295ZZblmuvvba22uiJp59+ulxwwQVlr732KrfccksZ0/bcc8/ay7nj7cILLxzjywEwWILkE044ofzwhz8sBx100EiPL7300mXIkCHl5ptvHuH+nEj83//+Vx/vzXQAAACDgcpkBr0zzjij/OEPfyjTTDNNrRBOxXB/DJa02mqr1UrfSL/kVIUdcMAB7X0qV1999fp9fwTJqS7bYostyre+9a3yve99r/3+iSeeuMfzWGeddcqVV15Zv//4xz8+Wsvzgx/8oC5TgpCeSlsOfZ6BCd2HH35Ydtttt3LmmWeWn/3sZ2WPPfbocrqZZ565/p7529/+Vh555JGy8MIL1/tb77ubb755r6YDAAAYDFQmM6idcsop5ctf/nKt6j3vvPPK5z73ufKjH/2oy2m/+c1vdtn7uKv7zz///PLWW2+V448/vlxyySVlySWXLKeddlqP59lb//znP2t/5gy8F21tbfV10/aip+aee+5aCZw2GdNPP32X0yQUX2ONNWrY0fLKK6/UYPzGG29sv+/hhx+uldkA9E6uysjVLHlPvv7668v2228/wi297VtStZz34xVWWKGGwqusskr5yU9+Uj7zmc/U32e9nQ4AAGBsU5nMoJUR7A8//PBapZUP2pHWE9/+9rfLuuuuW5ZaaqkRpr/11lu7HJSuq/unnHLKetthhx3KTDPNVMPqDKDUk+fGBx98UJ/fU+l5mcuYc1n0r3/96/Lcc8/VfsmtgfU6S9ic1+jp8rT85z//qeFGKq9bPaFfffXV2m85A+i1JNieZJJJerz8APyfSSedtH0w1c6tKTr2QI6Ewnn/ze+w+++/v75/5/da2ifld0JvpwMAABjbhMkMWqncTQCaIHaDDTaoH+DTfiI9jtMy4u9//3uZa6656rT//ve/yx133FHbRjzxxBNlvvnmG+X9qR77zW9+U3tRLrHEEjWATbVyR909N+HvXXfdVbbeeuser8sCCyxQB847+OCDy5133lnDgbTsSIh98cUXlwMPPLBMPvnk7SF6woR8TSuKXAI9quXpKBXHkYq2VF3H7373u/o167jpppvWwQUTWqh2A+i9tBl69NFHezx9qo3Tqqm/pgMAABibhMkMWueee26tzkp7hoTGCU/vu+++2js5Vb2LLbZYreZ68803a8uGVPIm6E3Fcqu/b1f3p2os92VAu1Ty5jbFFFPUAZSOPPLIGt5m/p2fm0rfBLDpa/n888/X6ujeSL/kXXbZpTz++ONlnnnmqcuSXps///nP67zTm3nYsGE1JE9lcaQqO5XTWabu1qUlAzVl+yRsTq/NhONZrwcffLA+nvYgWfasd6qVhckAAAAA9IYwmUEplbfpD5yeyek3nH7GqdKdaqqpyi9+8YtaxbvddtuVxx57rN4mmmiienlw2jcccsgh9fmjuj8mm2yyGiCvt956tTdyWkhEqpXvvvvukZ77wAMP1LA292egvlRL99aMM85Yby2Zf8LsVCdnPS+77LJ6fwYZzOum9UYGCUxV8qjWpWWfffYpW265Zdlmm23Kk08+We9LEJ2K5LPOOquuV3z961+vFd4AAAAA0FND2tKcFQaRtLZI1WwC1ASiqU5OkPzUU0/VlhetQexSXZuWEQmWU+mbwZAi091yyy1ljjnm6PL+VPMmSF500UXLtNNO2/66eb1UJA8fPry20+jqublvkUUWGWkAvLSXSFuKDOTXFwmFH3roobo8ec28TiQwvu2220a5LpG2GR2fl4GcWq0yFl988VqhnAruXJqdaWaYYYZ+Wf6E63nOPLucXIbMOHLbDRhdk07UVuaZuq089eaQ8v5HescyMMfYjfutXKabbrr63g/9LX9XvPbaa44xBoxjjIHmGGNMcJzhGBt7WtlOBhtPK9gmwmQGnYTFadlw9tln197GDF7CZAaaMJkxcYwJkxlIPhwz0BxjOMYYH3gvwzE27oTJSnAYdFIZ9vvf/77HA9ylRUWqbyN9hdMveFT3AwAAAAC9J0xm0Elrhwyy11M77bRT+/QrrbRS4/0AAAAAQO8Jkxl0ehMkR3cl+D0pzQcAAAAAemaiHk4HAAAAAMAETJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2GNk8CMGoXf231MmzYMJuJfjd8+PDy2muvlemmm64MHepXFgN3jAEAANBMZTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2EyQAAAAAANBImAwAAAADQSJgMAAAAAEAjYTIAAAAAAI2GNk8C0LX33nuvfn300UfL0KHeTuh/w4cPL2+88UaZZpppHGMMCMcYA80xhmOMcZ33MRxnjA+8l3UvmU7HjKeJ9Afos3vuuad+3XLLLW1FAAAAgHHU008/XZZbbrnG6YTJQJ8tssgi9esf/vCHsvjii9uSDMgZ0k033bRceOGFZaGFFrKFcYwxzvE+hmOMcZ33MRxnjA+8l3UvFckJkj/1qU+VnhAmA3027bTT1q8JkpdYYglbkgGTINkxxkByjDHQHGM4xhjXeR/Dccb4wHtZ13pSkdxiAD4AAAAAABoJkwEAAAAAaCRMBgAAAACgkTAZ6LOZZ565HHLIIfUrDATHGAPNMYZjjHGd9zEcY4wPvJfhGBt3DGlra2sb2wsBAAAAAMDgpjIZAAAAAIBGwmQAAAAAABoJk/n/2rsTKJ3q+I/jP1sqElGaUISUpFIqqnNkmSlliXBacIhSydKO0qKFCkVlSZHKFiGURLZkb0FHiDAqy0S2IdvzP5/v/9z7f55nxjx3mP4c9/06Z87M3OdrPPPM99zn3u/93u8PAAAAAAAAABKimAwAAAAAAAAASChv4hAAiHX48GE3efJk99NPP7kCBQq4unXruooVK/IyIVtWrFjhPvnkE/fyyy+7vHkzvh19++237vvvv3d58uRxt9xyi7vhhhuOKQbh888//7ipU6e6X3/91RUtWtTdfPPN7qqrrsoQ98MPP7hvvvnGHThwwFWtWtWlpKS4XLlyZTsG4ZOenm55sWzZMtt/XXrppa5evXoZ9mVr1qyx98udO3e6SpUquQYNGrh8+fJlOwYYP368W7hwoXv88cfdueee678gf/31lz22ZcsWd/HFF7vGjRu7ggULxrxgQWIQPtrvfPfdd5k+9sgjj7hSpUr576mff/6527Bhg0tKSrL8ic7BoDEIryNHjrh58+a5RYsWuR07drjKlSu7pk2b+o//+++/to/ScVuRIkVc/fr1XZkyZWJ+RpAYhM9zzz3nDh48mOljypOnn37az8EpU6a4H3/80Z1++unutttuc1dccUVMfJAY/B86kwFky/79+13t2rVd+/btrbiycuVKK9IMGjSIVxLZMnDgQNerVy936NChmO2RSMS1aNHC3XXXXVZc0UlwzZo13TPPPJOtGITTtGnT7ET2xRdftP2Vii8qAnfr1i0mThcxqlevbie+e/fudc2bN7d80oFkdmIQzgthF1xwgRVbVEBRge6BBx6wi6p//vmnH6eLZSoO64KELsI+9dRTdmFDuZSdGEAXTlV40Xvm33//7b8gc+fOdRUqVLCTX13k6tevn534btq0KVsxCKfp06dbTp155pmucOHCMR+6SO9d7NK+bciQIZY/Y8eOtYtn2md5gsQgvFavXm3HYXqfXL9+fYYLWSouX3fdde6FF16w4ys1iSifJk6cmK0YhNPZZ5+dYf+lD1148OoTqlmoMNyuXTs7N9A+65prrrH3Q0+QGMSJAEA29OrVK5InT57I6tWr/W3dunWL5M+fP/Lnn3/yWiJQDtWsWTOityB97Nu3L+bxcePG2fZp06b5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",
      "text/plain": [
       "<Figure size 1440x720 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "تم حفظ الرسم: saudi_labor_law_voice_agent_project\\05_reports\\figures\\01_ar_data_completeness_vs_retrieval_safety.png\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>المجموعة</th>\n",
       "      <th>العدد</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>أسئلة الفهرسة</td>\n",
       "      <td>503</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>أسئلة التقييم المعزولة</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>التسريب بين المجموعتين</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 المجموعة  العدد\n",
       "0           أسئلة الفهرسة    503\n",
       "1  أسئلة التقييم المعزولة    200\n",
       "2  التسريب بين المجموعتين      0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKMAAAHUCAYAAADm5evPAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAAT9RJREFUeJzt3QeYU2X6N+CXoqICYsEuYsMuihUrVlTsveta1u7quva+umvvrmLvdXXtvffu2iuuiopdsaEoku963u9K/jPDDBNgONPu+7qGzCQnycnJScj55Xmft0OpVColAAAAAChAxyLuBAAAAACCMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAGjVbr755tSrV6/UoUOHdPDBBzf36gDQiA6lUqnU2EIAAAAt1UwzzZQuu+yyNHDgwOZeFQCqoDIKAABo1RZddNH02GOPpeHDhzf3qgBQBZVRAABAq/XMM8+k/v37V/6effbZ04cfftis6wTA2AmjAAAAACiMYXoAAFTlxhtvzA2i11xzzQaXueOOOxpdpqXaZJNN8rpfddVVzb0qDW7H5ljHap731qRz58758fz0008t8rkHaA+EUQAAQKu2yCKLmEkPoBURRgEAAK3aHnvskU8vvvjiNHLkyOZeHQAaIYwCAKBFePvtt3N1yxZbbJH/7t27d5puuuma9D6+//77tNZaa6UuXbrk4VrtSRHbt7lss802qXv37unrr79O//73v5t7dQBohDAKAKCNiV44ETosv/zy+e84jb9//fXX1N5ddNFFOYj66quv0qhRoyba/UQoEtt8tdVWm2j3wf/p2rVr2m677fLv5557rk0zgbyHABObMAoAGKsddtghH1S//PLL6brrrsu/n3LKKRO81e655x49XqhlvvnmS6VSKe9n4cMPP8yhTlNaeOGF0zvvvJNve/To0e3qGShi+7aEoXpPP/10fr+i9f7/ALR9wigAgDZYJRKhwxNPPJH/jtP4OyqC2ru///3v6a233soNrzt16pRnipsYYvhbbPMHHnggtQdHH310mnrqqXMYETMBNof5558/rbzyyvl31VETxnsIMLEJowCAsbrsssvyQfWiiy6ae83E73/7298meKvFNPFxWyeccMJEfQbuvffefIDcsWPH9Pnnn0/U+2qNIoyJ7XPcccdVhuYMGDCg2dbnhx9+yOt04IEHpk033TQtueSSaeaZZ84Hx3feeecE3345mCv/bLLJJqmp1ezFFGFUbNODDz44tQQTY/u+//776eyzz06vvPJK3qbrrLNOau7qqGuuuSb3B6N1/v8AtH3tq2sjANDuRLAy5ZRTpp9//jndd999lb4ytCy///57OuaYY9KZZ56ZQ7H6xIEuLW/7Tj/99DnMevbZZ9MMM8yQJptssmZ7mjbYYIM0yyyzpE8//TRdfvnlaZ999mm2dQGgYSqjAICJKqotojKk2lm7omIqlo/hVDVFmLT33nunaaedNk0zzTS5V8l3333X6O3FgXG5iXRUSbUXZ5xxRurTp09+/PPOO2/617/+Ve9yURkUIcThhx9eGZrzyCOPFLquf/zxR1p//fXTP/7xj/w8R2XN+eefn1588cX0xRdfpJVWWqnB63755Zfp+OOPTyussEIOReLxzjrrrHnGvKjWaSh4mZhq9mKKfa+ICsCJtX2rEbc1dOjQtNlmm+WhoDGzXXOJGRJ32WWX/Pt5553XbOvRnt5DAMaHMAoAWsAQqeYc1lK277775nUZ20Hz+KzvRx99lE8XX3zxqpYvL1e+XrmqI0Kqc845J3377bc5hIqqh1VWWSWNHDmy0dscNGhQPr3//vvHWv3RVM9HNPON9Z1qqqlSz54903rrrVfp31SEGBK23377pffeey/99ttv6d1330177bVXHprVEv373/9Od999d/79+uuvT7fffnv685//nPr165cDpoY8/PDDaaGFFkqHHnpo3r4xQ1483qiKiQb5URUTDctr7kst4XVXzWutJWzfasWwrJpDH6+66qomWOux39/Ytl88tkkmmSS9/fbb6aGHHkpFau7XflPtf+PzHtLcryugdRFGAcBYpoCPD9ZrrLGGbTQBytVLs88+e9X9dsI333xTOS8qHOKAbsYZZ0zPPPNMrsKImcHiwO+kk05q9DbXXnvtfBphxUsvvZQmpuibs+KKK+YqrOjPExUycfAf1SdFVBZEVc7JJ5+c992LL7449825+uqrc8VIzHL15ptvppbmwQcfzKeLLbZY7mNUraiUi+c0rhP7RTzWUaNG5WqpqMjr27dv3h7tfXav8d2+rdVMM82Uh+sV3ci8uV/77fk9BGh9hFEA0ICorggLLLBAq9pGMUQpDiKGDBkyxmXRwDsu69GjR2HrUx4mFb1kqj2QDHEwV3bzzTfn00MOOSQtvfTSabbZZkuXXHJJPu+ss87KAcTYRA+ZaLBbxFC9qMr48ccfc9VWPAfx+E888cRcMRIVCS+88MJEvf94fKNHj07rrrtu2nHHHVP37t3TVlttVWku3FwznY1Nubqtvl5DI0aMyIFTfeKxhajYiP0i/o4Z8qIiJQLI2Abjsu+19tdaU2/fiW1ibr8999wzn956661p2LBhtbZFvD5iQoOmnl2y6Nf+xNp+rfE9BGh9hFEA0IAYGhammGKK8d5Gyy23XD4guO222+q9PIY/hPjGuT5R4REHE3EbN9xwQ9X9YcLw4cPHuCwOMBoytsuqXd/6xHCVUO3MVuXlytcLMTSvZlAV+vfvn+aZZ55cffDUU081ersxdCZEE/OmfHw1xXo899xzlYqMueaaKzdPj6Et0eMqQrO//vWvjQ5zKa/r+CxTriiLAK6mcmVazYqzcb3vapT3owiFqrXMMsvk02iAHZUYEZB8/PHHeVhmhMHlSoy6QyxPO+20HChEr6K4bk2DBw/Ow5BiGF8EAdU8z+V1rraR98R8rY3Pdmzq7TsuJmT/Gd/tN7bXaVQjxXMfr7kLL7ywcn70yYrHGYH2+L7Om+u1X9T+N77vIRP6/gm0L8IoAGhkuFh5iMv4KFduRKhUn/I39tGUuz7Rz6XcoyOayTYmDjLKjZPfeuutBu8vDkbrHniWA5+xVUk0tr71WXDBBfNpBHLV9HeK/jY1rxfKVU1HHXVUPuj75Zdfcg+TclD43//+t9HbLVe4xfWjeqGpHl9NNUPHySeffIxG4eHxxx9vMJz89ddfa52OzzJxAB6uu+66SsVE7H9XXHHFWCv9qrnv8kFvfQe/ZeX9Z1wqMuJgPZ7v2Cd33nnnfBDfq1evPAwv1r3c16juQXCELNdcc00+vzwUKqpRdtppp7T77rvnypHolRSN2at5nsvrXH4NNedrbXy2Y1Nv33F53qvZfxoKReob9lXN9pt66qnHevuxD4QIo8rVk6eeemo+LQ/jaypFvPaL2v/G9z1kQt8/gfZFGAUADYjGszGsJb7tjkCo/C10teKgInqIhOhnU58YQlLu5dKQGCYRQ0qefvrp9MADD4z1PuPy8kFXfNNeV7mJcVR9RXPfsjhYidsPY2v4W8361rX66qvnmfSiiXTMcjW2IXURuMV9RIVADAkpO/LII/MBThx0RbVZhFAxu1N5+0aVR2PKy8Zjr2/bjO/jq6nmLHTRK6ammgeEUalT34H9888/n09fe+21POtZfRpbJobWrLzyyrlX14ABA3Iz6QhqYhstssgiebjN+Nxu+WA6vP766w0GF+V9LBqHVyuez8ceeywPc4ohddF8OsKS2F/ieSs3oC/fdk0bbrhh3tbxWo3hetFXLIZwRuVcBI8RSFX7PEePqRDNzxszsV9r47MdJ8b2rfZ5r2b/qSm2XTlMiabqY9t+NcOq2H5PPvlk/j3257HZdtttU7du3fKQ63jO4/3lP//5Tw7j9t9//9SUinjtF7X/je97yIS+fwLtTAkAaNA555wTRxH5Z+655y4dd9xxpccff7w0bNiw0ogRI+q9zg8//FB67rnnSoMGDapct3PnzqXBgweXvvvuu7zMl19+WTr88MPzZV26dCl99tlnY30W4r5j2VlmmaX05JNPlv74449al//222+lxx57rDTrrLNW7jN+DjvssNLnn39eGj58eOnKK68sTTnllJXLVl999fw4Pv7449Iee+xR63r77LNPvqxsXNe3rmuuuaZy24ssskhel08//bT0+++/l77++uvS7bffntenvMzee+89xm28//77pW233bY000wzlSaddNLSfPPNl28rlt9tt90avO8vvvgib/vJJ5+8cvvTTTdd6cUXXyyNHj26SR5f+Pnnn/N6devWLd9O9+7dS1dffXXp+++/L73++uulvn375vNnn332fLriiivmbVDeZy655JJ8/fI6rr/++qUhQ4ZU1rGaZULsG++9915pjjnmqPWcxmOO/XLkyJG11rua24395+yzzy517Nix1v7zzjvvVJb56aefSieffHK+rFOnTvn5aioPPfRQvt0OHTrk9aj52vvll19Kzz//fN6eNR/v/vvvX/rggw9qbZvGnud4rcT5cfk///nP/Jjqmtivtca248Ybb5wvi/uY2Nu3mue92v2ypniMRx11VK3tcMghhzS4/VZbbbXK9tt9993zefPMM0+Dt1/TDjvskJcv3148lng/qmtCtuvEfu0Xuf+Nz3tIU7x/Au2PMAoAGnHVVVeVZpxxxlofysflp2vXrmO9PA72GrPccstVfX+bbLJJDmcaujwOlOo7PwKzuG7N83r06DFe61ufCy+8sDTFFFOMdd3jYHivvfYaI2xryJ///OfKgWwoH/TV9xMHoUcccUStxxQH+031+CJQi+ufccYZpc0226zedejVq1c+CB0wYECD69nYNqp2mcZ+yqHLuN7u4osvXiucqO8ngpymFuFSY+s288wz57Bisskma3TZhp7nM888s8W81urbjhMjjKpm+1bzvI/rfrnpppuO1/aL5zcCtPrEejZ0exGm3HrrrfVeb0K2a5Gv/SL3v/F5Dxnf90+g/RFGAUCV33xfd911pT/96U+lJZdcstSzZ89alTZ1A5WpppqqtOyyy+YAJipzdt1113ygXF4mrrvMMsuUbrrppqq2fxzIxPVWWmml0iSTTFLvwUWfPn1Kp556aiXIueKKK0rLL798Xpe4Tu/evXM1QlQ9xAFDv3798sFEHLCsssoqpUceeSRfL76lX2ihhXJQUz5AGdf1bUh8M3/00UfncG3aaafN6x3VBFHhtOeee5Zeeumlcbq9pZZaqtYBUH1hVFQIRGVFVBOEd999Nx8wxoFp3H9TPb6tt946H6x/9NFHuaLh4osvLi2xxBI5jJxhhhlK2223XX785cqQCN1q7kPTTz99afvtty8NHTo0V+TFNqn7XFezTDxvU089dX48Ua1w7733lk466aTSwIEDc4VduWKi5oFkNbcbVXkHHnhgfi3Ebca+VTP0iccSr436qk6aSlSbxHNeft7iJ9YzqmQOPfTQXGUSoqojtneEyPF6HNfX3fXXXz/G/RT5WhvbdpxYYVRD27ex573a/afu9jvttNOq3n6LLbZYZfutueaapWeeeabBx1A3jIrtGrcd1WZRNdSQCdmuRbz2i9r/xuc9pKn+fwDalw7xT3MPFQQAGvbEE0+kFVZYIffqKPc94v83Le/Xr1/eFO+8807q06dPs22W6IcV97/qqqumu+66y9MD7YTXPsD40cAcAFqwaNgdTXjD4Ycf3tyr02IMHTo0bbnllvn3COqaM4iKGQKjyXw0Co7Z/oD2wWsfYPwJowBgAsXU67179656+ZjtK37KU67HzHExS1WI2ZE+//zz9OCDD6bddtstz0r04Ycf5lmvNt1003b/XMWMUwcccEDeLlEN1b1793TppZc2yXZZYokl8nMxttn+6vrggw/SwIED86xUBx10UFp66aXH+X5j5ra434MPPjj/Hb/HuozrMkBxinrtA7RVnZt7BQCA/7PFFlukm266qfJ3TFd/zDHHpCOOOKLdbqZDDz00T/3+2WefpV9++aVyfgRSl19+eZprrrmabd0iGHv00UfzNPHHH398s60HUCyvfYAJo2cUALQgMfTskUceyZVWa6+9dtp+++1Tr169Unu2ySabVAK6nj17plVWWSVttdVWadCgQalTp07NfkAaFRGxjkD74bUPMGGEUQBAi/b222+nESNGpFlmmSXNMMMMzb06AABMIGEUAAAAAIXRwBwAAACAwgijAAAAACiM2fSgCsOHD8+zJc0222x5ZisAAADg/xs5cmT6+OOP00orrZR69OiRGiOMgipEELXBBhvYVgAAANCAW265Ja2//vqpMcIoqEJURIUbb7wxzTfffLYZbcqoUaPSjz/+mLp165Y6d/bfAm2L/Zu2zj5OW2b/pi0b1cY+gw8ZMiQXcJSPnRvT+h8xFKA8NG/uuedOCy64oG1Om/uPMIaiRjltW/iPEGqyf9PW2cdpy+zftGWj2uhn8Grb2mhgDgAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhOhd3V9D6rXfOE6nDtJ8092pAk5q0Yyn16lpKQ3/qkH4b3cHWpU2xf9PW2cdpy+zftNf9+8MTBqW2TmUUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEU7UqpVErffvttGjVqVHOvCgAAALRLnZt7BaAoP//8c1pyySXT559/nh5++OHUt29fGx8AAIBW6YUXXkiPPPJIvZfNPvvsadNNN61VmPHkk0+mV199NU0++eRplVVWycvU9emnn6YnnngiffHFF2n66adPyy67bOrVq1eTr7swinbju+++yy+22267Lc0666zNvToAAAAw3iKIOuCAA+q9bNVVV62EUb/++mvaYIMN0r333lu5vHPnzumss85Ku+++e+W8rbfeOl177bU5uCrr1KlTXubss89OTckwPdqN559/Pv8ss8wy6fLLL2/u1QEAAIAJdtddd6Uff/yx1s8dd9xRufzYY4/NQdT++++fPvvss/Taa6+lxRdfPO29997pzTffrCz33HPPpa222io99dRT6euvv86nCy64YDrnnHPSPffck5qSMIp2Y8MNN8wvqPjZddddm3t1AAAAYILFsLuuXbvW+unSpUu+LKqcLr744jTvvPOmk08+Oc0444xpoYUWSoMHD05//PFHuvDCCyu3c9lll6Wrrroq9e/fP0077bT5NAKs8N5776WmJIxirH744Yecqpb99NNP+byJdfsTW1OvPwAAALRU77//fu7/NGDAgNShQ4fK+Ysuumiaeuqp02OPPVY5b7nllhvj+tFnqmPHjmn55Zdv0vXSM2oiNMmO5HGSSSZJI0aMyE9uaxYlepGo3njjjfnv3XbbLTcAf+CBB5pkO2y22WY5tS3f/sRW7foDAABAa3Drrbem//73v2mqqabKbWkWWGCBymUffPBBPo2KqLpmmWWW9L///W+M8x999NH00EMPpccffzw9++yz6dxzz02LLbZYk66zMKqJHXXUUWnkyJE5UTzttNPymMuW7LfffsvVQtNMM0273g4AAADQGp1xxhm1/t5ll13Seeedl5uPl0cGTTnllGNcL86rb+TQ7bffnk499dT8+0477ZQGDRrU5OssjGpip5xySuX3LbbYIrV00cTs4IMPTm+88UaL2g6jR4/Os99FSFazlLAIX375Zfrqq69qnTdkyJBC1wEAAADGZoUVVsiNxeebb77cNyoak//tb3/LfaCikqnmTHkxe15dMfyuPv/85z9zThC3t++++6ZFFlkkvfzyy6lXr16pqegZNZH9/vvvuUKopVp33XWbPIia0O0wdOjQNOuss+YGa0X2kyqLEsRo6FbzJ6bBBAAAgJZi6aWXTgMHDkyzzz57mn766dOqq66arrnmmnzZzTffnE+jLU749ddf622vU768pkknnTRNN910aeWVV84VVlEocsIJJzTpugujmliMq9xhhx1Sv3790swzz5wmm2yydPrpp6fm0lgAFH2dJkZYNiHb4dNPP02rr756evHFF3O6W7Q99tgjvf7667V+brnllsLXAwAAAMbFPPPMk0cXff/99/nv3r17V4o+6ho2bFgOssamfPmHH36YmpIwqgn99a9/zQ2/Iz28++678xPbvXv3ZpkFLpqMxU4YYc6aa66Zr1/fuNIePXrkcaLrrbde+vbbb1vEdnj66afTnXfemRZffPH08MMPFz57XiTKCy64YK2fueeee4LWAwAAAJrSq6++OsZ5MZwuik4iDwhxOu2006ZHHnmk1nLvvPNO+vrrr1P//v3z3zHRV912NeGFF17Ip42FVuNKGNVE3nzzzVz5c9JJJ6Xtt98+zTDDDFVdL6qSvvnmm1rnxY4TO0UMbSvba6+90kYbbVTVbcb1ok9T9DmKiqToC3XmmWeOEfjst99+eRhczHgXDcr+8pe/pObaDnXDrOjoH13/11hjjcK2GwAAALQWyy67bO7tFFVLcTz8yiuvpJ133jk3Lo/j6nJfqG233Ta9/fbb6eSTT06jRo3Kx9L77LNPvjyO20PcRvSGOv/889Pw4cPTH3/8kWfVi+XiNqKReVMSRjWRzz77LJ/ef//96eOPP85hTzxZjVXlXHnllXks5i+//FI574svvkg9e/bMIVJjInypW/X07rvv5h1p8ODBacSIEbmpWUzzWFNM0RgVUe+9914OpDbffPM8tK65tkNdm222WfrTn/400bYbAAAAtGYzzjhjOvHEE9Mcc8yRi0wWXXTRXCASo6CiZU7ZMccck0ceHXjggalLly75WPq+++5Lhx9+eA60QkweFkUfu+22W5p66qlzYcuAAQNyxdQFF1yQllhiiSZdd7PpNZF4YuPJu+qqq/JPTfWVupWVq3iiiXj5yY0nu9xMrGboVF9jsehsHyFSpJzloXCxbNhwww3z7zE2dMUVV6x1veisHw3M4noxVC/uc+GFFx7j9iPommqqqSbadoidPWbOq29Gu/qGFjbVdgMAAIDW7L333svD72LWuyjOmGmmmXILnrqz3kVWEIUi0Qs5hvZFO5/o07zkkktWlunTp09usRP5Qgz1i6KVmFgsbm+22WZr8nUXRjWRCHTuuuuuXCIXO0SMpzzggAPSoYcemq644oo0aNCgPDtcpItlUS0Uw+NCDJk7++yz804RtxEifVxqqaVyA+0HHnggDzmr6+ijj05XX311Lq2LVDN2uvLwtZiOMS6LhDRuvxwIRZATM8RF9dE666yT12mKKaZIt912Ww5vYh2iauqtt95KzzzzTJ4asim3QyS0sVxUcD3//PM5kLrhhhvyCyHWI7r+RyVXNF276KKL8owA3bp1a9LtBgAAAK1Zhw4dcq/m+GlM5AKbbrpp/mlIVE2tvfba+Wdi61CKgYVMNDFUbvfdd6+U0JWrd2ruENEcO4KfsYkxnxGuzDfffLXOj6cvbiPGc9Yngp/DDjssB0R33HFHTktrirGfsV6RgJZFA7NoZv7+++/nnTuqj8rNz7bZZpv8GCLkGd/tEIFZhE7RF+q3336rtS7lKqlIdKNyK6aQrHn+hG638V3/2AYR4PXa+ZzUYdr/PxsBtBWTdiylXl1LaehPHdJvozs09+pAk7J/09bZx2nL7N+01/37wxMGpdamfMwcx98xCVhj9IyayGK85SWXXJKHwEW1UXSxj58YoxlBUcwa9+STT+agZs4558xlcBGYxPlrrbVWriyKIXYxnrNuEBWimimCqLj9CHhiiFz8hMsuuyz3i4rk8+KLL85BVOfOnXOV0cwzz5xn2YtSvQiFoooqdpxYrxDTQC6//PK591M5iApx3XEZtlffdoggKSqwYge98MILc3P1vn375vWP+49hd1Eddeutt+ZtFOc31XYb3/UHAAAAmobKqFbok08+yTPlRVgTFUcx5C0CpRiqFmLMaJTpxfC2Bx98MI/vjJnyokl5hDaMO5VRtGW+daQts3/T1tnHacvs37Rlk7bzyig9o1qhms3Dosv9jTfeWAmiaoogapdddkmnnnpqrZ5LAAAAAM1FGNVKw6jevXvn4Wg777xz6tmzZ63LYxhcDGmL5t7RLwoAAACgpRBGtUJDhw4d6+XLLbdc7skEAAAA0NJoYA4AAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABSmc3F3Ba3fbXstn/r27dvcqwFNatSoUWn48OGpR48eqXNn/y3Qtti/aevs47Rl9m/aslHt/DO4yigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwwigAAAAACiOMAgAAAKAwnYu7K2j91jvnidRh2k+aezWgSU3asZR6dS2loT91SL+N7mDr0ub276f+ukxzrwYAADWojAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjAIAAACgMMIoAAAAAAojjKJdefTRR9NJJ52UPv/88+ZeFQAAAGiXhFG0G59++mnabbfd0tdff53++OOP5l4dAFqYUqmU7rrrrrTzzjunxRdfPC2xxBJp2223TS+//HK9y1588cVplVVWSQsuuGAaNGhQuuOOO8Z7OQCA9kQYRbvxzTffpFGjRqWOHTumzz77rLlXB4AW5rHHHsth0XXXXZemn376NN1006Xrr78+B1O33XZbrWUPPPDAHFrFFx3zzz9/evXVV9O6666brrjiivFaDgCgPRFG0a5svPHG+XTkyJHNvSoAtDBRxbTTTjulTz75JN19993pnnvuSU888UTq0KFDOuKIIyrLffjhh+n0009PAwYMSG+88Ua68cYb8+k888yTDjjggPTbb7+N03IAAO2NMIp2Y5FFFkknnHBC/lluueWae3UAaGGWXXbZdNFFF6UePXpUzltqqaVSnz590jvvvFM57/bbb8/Dvffdd9/UuXPnfF737t1zBdSXX36ZK6zGZTkAgPam1YZR8e3iLbfcklryOkVPiCj1b80m9mO64YYbCn0e28JzAsDEMemkk9Z7/vfff59mmGGGyt+vvPJKPl1ooYVqLbfwwgvn03KPqWqXAwBob/7/13QtyL333pv7+vTq1Ss99dRTadddd613ucsuuyx16dIlbbDBBqmlqLtOEXrErG1bbLFFaq3G9zFV+zxecsklqWvXroU9j23hOQGgOA8//HAaNmxYrmYqK8/IOtVUU9VatmfPnvk0+kONy3IAAO1Ni6uM+uWXX9KIESNyH4Uff/yxuVenTXj00UfTf/7zn/Tee++ls846q5D79DwC0Nr9/PPPeRbWKaecMh188MG1/o8LU0wxRa3lJ5tsslqXV7scAEB70+Iqo2pWyMTsNUy4+LAbH6h///33PNSgNTyPMWvRW2+9lftslD+0FyX6eHz11Ve1zhsyZEih6wBA84peT1FFG1/kXHPNNWmuueaqXDbJJJNUGp7XFBXBNYf7VbscAEB70+LCqBDBSTQK/eijj3KJe4QZ0UCU8bPmmmtWfl9ggQXGCKrOPPPM/M1vTF8dzVvLvSya63mMmYuOPfbYtOqqq47xAb4I5557bjrmmGMKv18AWob4v2eXXXbJfQb/9a9/jTG0e7rppsunUcEdVVNlw4cPz6fTTjvtOC0HANDetKhhep999lnaaqut0pxzzpmOOuqo9MADD6T99tsvPfTQQ1Vd//77789BQtxOXVERFLOo1R36Fx84X3jhhTR48OB09tlnp/vuuy/9+uuvqS0ZOXJkbhR+/vnn52mm6z7++FAc3wDHtmmKaaYn9HmM9YmQLL5Rbo5+GnvssUd6/fXXa/20tGb5AEwc8f/in//859wz8bzzzsv/J9Q133zz1WpQXhZVVDUvr3Y5AID2psVURkUIMmDAgPzB7H//+1/lG8Srr766quv/7W9/S6eeemr+PQKQZ555plZJ/ejRo3PIUbPS5osvvkgbbrhhevrpp2vd1iyzzJJuuummtPTSS1fOe/zxx/OsN3GbUWnUsWPT53gRFN15552pW7duad11101TTz11kwRRUe300ksvVfpWxDe9K6+8cuXvCOnK27C5n8cQ11lnnXXysML4mRCxPSNkG5eG5dNPP33+AaB9if9zdthhh1wpHBNsxO/1WWONNdIRRxyR+zEOHDiwcn588dO5c+e0yiqrjNNyAADtTYsJo5588sn07rvvpqOPProSYHz33XeVvgpj88Ybb6TTTjst9evXLw8xu/LKK3MgddVVV1WWiWCnHLqUxeURRC2//PL5uvHB8IMPPki33357OuOMM9K1116blzvyyCPzsLGyFVdcMd19991jNCSdELEeq622Wm7eHqaZZprcN2m55ZYbY9n4EBt9JurOQFff+XFeBFFx2xGkxWM+8MAD0/PPP1/VbRb5PJZFUBY9m2J9GvrW+NVXX83PwUEHHVRrWGBUt2266aaVIPLf//53+uSTT8yeB0CjTjrppNwfarPNNsufCWp+jigPdY/PCzHkPIaSX3jhhXm5OC+qgB988MFcSVWeLa/a5QAA2psWE0ZFNVA49NBD09tvv50DhKhOioAhhpDVVbPC6dlnn81/33PPPfmDXa9evdLJJ5+cy+vLtxvi75heOYaQhbXWWisdd9xxeWhfuU/SN998kyuJypU0EQ5FiNWnT5+09tpr56Dlrrvuyt90liux6luncRUfSuP6O+20U/77xhtvzKFKNPGuOyV0fKjt2rXrGMFRfedHqNO9e/d077335mqu6F9xxRVXjHH/Dd3muD6mcX0eG9LQ+pQ999xzeWaj6OkRwV059DrkkEPSQgstVAmjIgTr0KHDOD0GANqn8lD++IImfuraf//9c6AUrrvuutxvMYbAx/9vXbp0Sbvvvnv+cqymapcDAGhPWkwYFc2t49vD+Lbw73//ez4vQqUomY/hcfUNaStXDZWHVG255Za5ail6M0Tfpxgm1rdv38p1IpTYdtttc1ARQ/DiG86oolphhRVytVDcX1TaHHDAAWn99dfP14kKoliH+La0fN7GG2+cK6dWWmmltN5669W7TuMiwrR4jJtsskm66KKL8nmDBg1KG220Udpxxx1zdU95WGAMu4tKsKgaivUqz9TT0Plxm//4xz/yaaxvNGLdZ599at1/Q9cdn8c0rs9jNDaPyyL0KodGY1ufsvKsgBEMbrPNNvn36P0Vorqt7M0330wLLrhg1esPQPsV///vvPPODV5e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UQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQGE6F3dX0L788MMP6e23306TTz55WmCBBVKnTp2ae5UAAACg2amMgongyCOPTNNPP31aeuml0yKLLJJmn3329NBDD9nWAAAAtHvCKGhiF198cTr22GPTCiuskG677bZ0+eWXp44dO6YNNtggDRs2zPYGAACgXRNGFWCdddZJm2yySeXvbbbZJq222mpF3HW71xzb/tRTT81VUbfeemtad91103bbbZcuu+yy9OOPP6bBgwe3++cEAACA9k0YBU3oiy++SG+99VYOvKaYYorK+SuvvHLq1q1buv/++21vAAAA2jVhFDSh9957L5/26tWr1vkdOnTIfaPeeecd2xsAAIB2TRgFTei7777Lp1NOOeUYl0011VRp+PDhqVQq2eYAAAC0W80aRn399de5YmTIkCFp7rnnzn11aooD97/85S9pjjnmSJNNNlmac84505577pk+/vjjZltnWpbG9qGijRo1Kp/G/lpXNDGPIOqPP/5ohjUDAACAlqFzc975dNNNV6kSiTChpt9//z0NGDAgvfLKK5XzPvjgg3TuueemkSNHposuuiif99prr6UddtghD4/acccd02mnnZYP+sdVly5dcqgRjaf79u2bll9++bThhhumeeaZZ4IfJ82zD42vL7/8Mn311Ve1zqv2tssVUbH/1vXrr7+mSSedNHXu3KwvOwAAAGhWLXaY3r333puDqK233jr973//ywHU+++/n8OmGWaYIS/zyy+/pEGDBqWXXnopz1R25plnpjPOOGOM24rAarnllstBwSKLLJJuu+22eu8zwoKhQ4em22+/PR100EGpT58+adlll00333xzuuCCC9Jhhx02XrfbEqy55pppiy22aPDyCFsijJvQBtuN3c+EKmI2vAg8F1pooVo/G2ywQVXXnWWWWSqNzOsLuWadddYmX18AAABod2FUVBU98MADVQUVm2yySVXnx4F7VDhFBVQM04uKkhimt99++6V//OMfeZn77rsvD9m79NJL02effZYWXnjhdNZZZ6XRo0fXuq3NNtssPfXUU2nEiBE5QIqKp0ceeWSMICouj9t7+eWX0913351OOOGE9OGHH6aNNtoo7brrrunTTz8d59ttKhO6jRvzzTff5NOoDKtGv3798pDJphLPc4RhETqWff755/m8O+64Y6I97vrsscce6fXXX6/1c8stt1R13Qgwu3btmp588skxhhNG0LnYYos1yToCAABAuw6jIsipplrl22+/rYQejZ2/4oor5iDi8ccfH2P5CH9iGFUc4If11lsvzTjjjOmAAw5IH330Ua6gKovf33777XTyySfn9Xz11VdT796900477ZSrqWqafPLJc+XK/PPPn/tV3XTTTTnkivWIap9jjz12vG431neSSSZJzbmNY3tFSNKQaaaZJp/ec889Va3Pb7/9NkY4N7b7WX/99XOoGNVs9Smvc83Z5srPbzz2mg3Cf/rpp6of9/hs+wjkFlxwwVo/0Y+qGnFfUUX14osv5uq+sth3Yjjh5ptvPk7rAgAAAKm9h1FRsRThTEONon/44Yd8ef/+/XMwFKJh84033pheeOGF9Nhjj+UqkzivofNDHPxHtUxUH/31r3/N97fvvvumpZdeOvXo0SNdffXVuTonREVSXD/CjvDJJ59UQozLL788//7mm2/mkCh6DEVoFEP/1l577XwaIcGwYcNyBc5uu+2WZp555rTlllum559/Pldkxem1116bZptttnG63RDb4Nlnn82XNcc2jobacf5///vfNNdcczV4n9EbK0KXQw89NO2+++7piSeeyAFP3Wbb33//fTrnnHPSG2+8kYOrhx56KFeiNXY/xx9/fK4yi9uu2Y8ptn1UlcUwyBDDI+P5i2Dp73//ez7vqquuytv4mWeeyZVn8RhvvfXWfJ9j24fGZ9s3heOOOy4HWmuttVZafPHF874cFXtRvbXxxhsXui4AAADQ4pTG0csvvxzdoksvvfRSg8tMPfXUeZn46dmzZ+X3aaedttS1a9f8e8eOHRs9v6GfySabrHTFFVfk+9ppp53qXWbRRRet/D755JOPcfmAAQNKHTp0qPe63bt3L+29996lCy64IP992mmnlX7//fd8f3vuuWfVtzvffPOVunXrVurUqVPplVdeqWyfrbfeurTqqqsWuo27dOlS+uSTT8b63L744ov5+o1t//iZccYZK48/no/G7mf06NF5O4ztNmedddaq7ru+n5qPO+5nueWWG69t35DXX38933Y8N9UYNmxY6aCDDiqtueaapQ022KD0r3/9q7IPQUsT++ZXX31lH6VNsn/T1tnHacvs37RlbW3/Lh8zx2k1xrkyqjxLWPRWqk9UvUTlzgILLJC6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fTyC0sGDB1eWiZBqiSWWSMcee2xeJg7G559//vwF2rgsA80p9svtttsu76PXX399rct23HHHtOGGG6bhw4enL774Iq2++urpb3/72zgvA0W74IIL8vt2jx49av1MNdVUlWWuvfbaHC69+OKL+TP1IYcckpZffvn8WXtclmn1SkC9TjzxxFKnTp1K7777buW8ww47rDTZZJOVhg0bZqvRol166aWlddddt9S5c+dSvNW/9tprtS5/+eWXSx06dCide+65lfMef/zxvOw111xT9TJQtM8++6zUr1+/0ueff14576mnnsr75XHHHZf/HjVqVGmOOeYorb322pVlfvrpp9LMM89c2mqrrapeBprDiiuuWHr44Ycrf48ePbrUv3//0uSTT1765Zdf8nm77757qUePHqVvvvmmstzWW29dmmGGGcZpGWhOhx56aKlr166lbt26lQYOHFg5/9Zbb83v6XfddVflvCuvvDKfF+/31S4DzWHeeectLbfccg1e/t1335W6d+9e2mOPPSrnffrpp/k9Pl4T1S7TFqiMggZcc801ackll0zzzDNP5bwtt9wyjRw5Mt144422Gy1afAMTpeoxtLQ+8W1LfCMZ+3RZfNsy22yzpauuuqrqZaBo3bp1S3fffXetYaf9+/fP5e/PPPNM/vvpp59OH3zwQdpqq60qy8RQ6/XWWy/95z//Sb/88ktVy0BzuPTSS/Nwo7IYfrrQQgvlfTJ+4hvyqCJZc8010zTTTFNZLt6rozrk/vvvr2oZaE5XXnllHp4Xn7dr7qMhzothpbH/1qwYnGSSSSqfP6pZBlqiqE794Ycfan3+mHnmmdNKK61U2XerWaYtEEZBPX7//ff0+uuvp7nnnrvW+X369MkfCl966SXbjRZtgw02SAcffHAuWa9P7MPTTTddDq3q7uPl/buaZaBoERhNP/30tc6LIRpxkD7ZZJPlv8v7Z9338BiSF0P53nzzzaqWgeYw55xz1vr722+/zUNJ11hjjXzw/eGHH+bz6tt3Q+zb1SwDzeXJJ59Mu+yySzrppJPSuuuuO8blsX/G0NSafQC7dOmS+6bV/IzS2DLQXD755JN0+OGHp2OOOSZ/MVDzC66xff4YOnRoHmJdzTJtgTAK6hH9daJ5eXwDX1N82xKNbT/77DPbjVYt+uzU3b9DfDsZ35pHRVQ1y0BLcNlll+XT6BsVYt8Ndfff8rfv8R5ezTLQnP7973+nnXfeOTfoX2eddfLfwf5NaxZBafR52mabbdL+++9f7zJj+/xRfm+uZhloDrFf77bbbrliO0KpnXbaKS2yyCI5RArew/+P2fSgHjEUL8SbSF0RSBm+QVvYxxvavyNkisqQapap73Io+sAmZqeJpublmZgaeg+PfTfEe3g1y0BzmmKKKdJMM82UvwmPoakxi1LMZmr/prWKYUcRrEZT5vPOO6/B5cb2+aP83lzNMtAcouqvpr333jtPJrHvvvvmNgDew/+PMArqEWW+Iaqj6oqZ9RyA0xb28fJ/hnX37yh5j8urWQaaU8woEwfosU/GzDXlb8kbeg+P5UK8h1ezDDSnQYMG5Z9yL5xNN900/e9//7N/02pFqPrGG2/kg/Ujjjiicv53332X3n333dxe4C9/+Uvexxv7DF7NMtASRFVU9Fx94IEH8t81P3907ty50c8oDS3TFhimB/Xo2bNn/mYl+pDUFG8AcfAzyyyz2G60atEEse7+HWIMenwTH2FTNctAc4n34zg4f+utt3IQtcwyy1Qui3031N1/yz0W4j28mmWgpYjJKH788cf07LPP2r9p1Qflxx9/fO6LVnPK+44dO+bP3fF7p06dxvr5o/zeXM0y0FJEuDRixIj8u88o/0dlFNQjEui+ffuO0QDxnXfeyaf9+vWz3WjVolw4GuIOGzas8p9ieR8v79/VLAPNIb4p3HrrrdODDz6YG4NGdVRNse+GeA8v/17ed+PbxPnnn7/y7eLYloGiRdPxOGCZddZZxxjeVLNBczTxH9tnlGqWgaLF+2p9762DBw9Oc8wxR66MCvGeHMOZRo0aVakKidfFxx9/XKkWrGYZaCmi8q88gUTNzyhrrLFGrffn3r1754kqqlmmLVAZBQ2IxopRShyz6pVdccUV+SAlyuWhNYupYuObyKgoKYsD+wiett1226qXgaLFgUfsm3feeWc+EIlGuHUtueSS+UNfBFXlRvtxMH/rrbfm9+84oK9mGWiOMGrVVVfNBy5lUZF90UUXpfnmmy+tsMIKuSo1XgOPPPJInkyi5meUqFqN61ezDLTkz+ARLN12222V86699tr8/l/+/FHNMlC0mIm3HPqX3Xjjjen9999PBx10UKXSNRrtX1fj8/VHH32UHn300cq+W80ybUGHkumQoF6///57Psh57rnn0mabbZY/zN1+++3pwgsvbFNvArRNV199dXrttdfyNyr3339/nsljuummS1tssUVadNFF8zKnnHJKnnZ24403zr124kNcHITHQU95CF41y0CR4kNdDM8bMGBAWnrppce4fMcdd0x9+vRJzzzzTP52fKGFFkqLLbZYrvKLb88feuihXDESqlkGip7Nt3///rm6Y6ONNsrDlu66667czPyGG27IM+uF77//Pq2++up5+fXWWy8f/Dz11FM5oF1ttdWqXgZagqj0iLA13oPLonfUxRdfnD+3RDVsHJTHwfzRRx89TstAkeL9NT4nx/t4VKDG++9NN92UP4dH0/7yZ+f44mvLLbfMXwxEVWBcb+65566831e7TGsnjIKxiKw2vlV89dVX84s+yiRjxiZo6W655Zb09ttvj3H+uuuum2exKYtlHn744fxNYlSK1Oy7My7LQFGiR1R8QGvI5ptvnj+0latM4kNbfBiMHiVrrbVWmnTSSWstX80yUPRnj/giLL5MiFnBYr+Mb8nr7pfxnnzfffflkCmGbMQydUPUapaB5hYH6dNOO23+8remF198MT399NP5AH6llVbKXxzUVc0yUKQPPvggv4dHIUP0Qov9coEFFhhjuWHDhuUANqqy4/L4kiBGJIzrMq2ZMAoAAACAwrSdWA0AAACAFk8YBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAIyzESNGpA8//DCftnQfffRR+vrrryt/jx49Oq/7d99916zrBQDtlTAKAIBaRo0alcOazz//vMEtc99996U55pgjn7Z08847b9p3330rf//www953f/xj38063oBQHsljAIAoPYHxI4d0yqrrJLmmWee9P3339s6AECTEkYBAFD7A2LHjmmfffZJP/30U7rgggtsHQCgSQmjAAAYw0477ZS6d++ezj777DxsDwCgqQijAAAYQ7du3dLOO++cPv7443TDDTfYQgBAkxFGAQC0E99880369NNPKzPMRSPvsYmhep06dUqnnXZaas9+/vnn9NVXX1W9fMzcFw3gf/3110aXHTlyZH5O9OYCoD0RRgEAtBMnn3xy2m677fLvq666arr++uvHuvzss8+eNtpoo/Tiiy+mxx57rKr7iIArgq4ff/wxtRURRC288MLpgQceqGr56LMVs/VdfPHFDS7z/vvvp/XXXz9XoM0666ypR48e+XSPPfZIQ4cObcK1B4CWRxgFANAGffvtt7k6548//qicd8IJJ6QHH3ww/z5kyJC0yy67VC775Zdf8vLRtLymv/71r/n01FNPrTqI6d27d+43FQHLeuutl84777w0fPjwNDF99tlnlaqvpjbllFPmKqeBAwemv//976lUKo11+Q022CCf3n777fVeHmFT//7902233Zb7cc0wwwxpqqmmyusf2+qaa66ZKI8DAFoKYRQAQBu01157pXnmmafq5uOvvvpqruaJMKSmZZZZJv/ccccd6b333mv0diJU6dWrVz6NKqkIZKLap1z1E6FRWVM2Rt9www1ztdfE0LNnz/T666+nVVZZJR111FFp6623Huu6L7DAAqlPnz7pkUceGSPcCyeeeGKuttpmm23Sl19+mT7//PMc1kVFWYR+M80000R5HADQUgijAADaoC+++CLNNttsabLJJqtq+bnnnrtyvbqiOmr06NHpjDPOqJxX7jdVs/IqRLVVhCoRrkS11ZNPPpn++c9/5tuPoGveeefNwwUPPfTQHO40JCqR6qvUCnF+9L8qUoRp9957bzr44IPTtddem3bcccdGq6OiH9T9998/xmUx7HGaaaZJl156aZpuuukq50eIF9t6++23nyiPAQBaCmEUAEAbNPnkk+fqm99++62q5T/55JPK9eqKvlHRP+qyyy7Lw//CzTffXGnW3ZAIwpZddtl0yCGHpJdffjmHLyNGjEgHHnhgOv7448faV+qZZ57JlVoXXXRRrfOjIinOP+igg2qdH48zArO6IiyL60wyySRpQnXs2DGv9xFHHJGuvPLKdNNNNzU6VO+WW24Z47IYlte5c+d8ewDQHvkfEACgDVp66aVzVVEEP/WFNDXFcuXeUHG9umJGvZhZL4KkwYMH575Q5ZAlqoXGJmaJi+BmzTXXzNVEEQ5FL6moMKqvaqgsqqvC888/P0ZVVPl2y37//fd8fgRqMfNdTa+99lq+z6g6aipHH310Du3+85//NLjMYostVgnt6lZ3xbaMoDBCurr9p2JdY52jpxcAtFWdm3sFAABoervvvns6++yz05lnnpkeeuihPPSrX79+acYZZ8wVSzGE7uOPP05PPfVUrj6KXk5LLrlkWmuttSq3EcFOhCZhwIABuZongpgIf+I2oloqwpZzzjknXx5BSjT7jgbdL7zwQm6W/uijj+bhamVx/1dffXWuboqQJiqrunTpUrk8qpjeeOON3Jsp3HDDDWmRRRbJ6xWVVDG8L0QPqwiDYvjf+eefn7777rt8fjzO/fffP00xxRQ5sCqHbNH3anxEP6cYMlhzeGIM04vtN/PMM1eCs5qhUjymWKcQ6xxDF/fbb7/cRyu221xzzZWOO+64vC3juVl33XVzkBZ9u+Inbvv0009P++6773itMwC0dB1KjU0HAgBAqxRNtzfbbLP01ltvNbps9G+67rrrcrPusquuuiptu+22Yywby1xxxRU5WFl99dXH6BtV0yyzzJLXYbvttkvHHnvsGNVEUWEU4Ut9VlhhhfT444/XW6lV9z6j91KEZDUrpsoiKHv44Ycrf0c/q6mnnjqHVqecckoam+WXXz73vaorZguMCqaouIqQrr5tECHaO++8UyuMa0wM3YvG8yeddFKeiRAA2iKVUQAAbdRCCy2UK23uuuuudM899+SKo6h0inAkKodi1rYITNZff/0c/NTVtWvXXP0UoudSNPGO4XZR6RMNuMsVSjEDXAQzcbtxm1H11L9//7TGGmvkaqsOHTpUwq0TTjghD+2L9YgAJ74XLV9eDmMi4Nlzzz3TpptumvsyXXLJJen999/P6xC3GSFSVH1FUBWNzGNIXFQZRd+oqKiK8Ch+j/UdOHBg7vFUU9xHPK7yYxibeDzlbRDrGUFc3N9hhx1WGfrXu3fvyux6sUwEXdEz6oADDsjbP/pMxXDDeKxRBRbLRKAWVWRRKRaVUjEDX9++ffNPbHcAaMtURgEAAABQGA3MAQCYqKI3VbmnEwCAMAoAgIlqo402Suedd56tDABkhukBAAAAUBiVUQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQGGEUQAAAAAURhgFAAAAQCrK/wPwsWg+acMaRAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1200x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "تم حفظ الرسم: saudi_labor_law_voice_agent_project\\05_reports\\figures\\02_ar_faq_split_without_leakage.png\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>الاستراتيجية</th>\n",
       "      <th>عدد المقاطع</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>التقسيم الهيكلي</td>\n",
       "      <td>722</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>التقسيم بالحجم الثابت</td>\n",
       "      <td>719</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            الاستراتيجية  عدد المقاطع\n",
       "0        التقسيم الهيكلي          722\n",
       "1  التقسيم بالحجم الثابت          719"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABCsAAAHUCAYAAAATN6I6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAATatJREFUeJzt3QeUHMW1MOASiJxzzkLkLDAYgchJIHLOyWAyxsZgwJicMTwTn8nZZIzJORiTcwaRo8ggEQXzn1vv7/VskmZXO7ut0fedM1rtTE1Pd1dPb9ftqlu9KpVKJQEAAACUxFg9vQIAAAAA1QQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgCqDBw4MM0888zpqaeeanrulVdeyc8tt9xy9lWVRtkvjbIdjeqtt97K9bPMMss0TP06z5RDGY8N4L96V/0fAMZ4H3/8cXr//ffTDz/80LQvfvrpp/zc+OOPP8bvn2qNsl8aZTsa1fDhw3P99O7du2Hq13mmHMp4bAD/pWcFAAAAUCqCFQBQZ7vvvnvuajx48OB01VVX5f9fcMEF9juAcyXQDsEKAEZLRx55ZG70P/jgg/kR/z/mmGNSGX322We5q3F0OR42bFj+/9ChQ3t6tYDR8HzSyMp4rnRsQM8RrABgtPTll1/mC9nvv/8+P+L/X331VSqjM844I7377rupT58+aZNNNsn/33777VOZvffee7nBttNOO+XfV1hhhTTPPPP09GpBGtPPJ42sM+fKhRdeOC255JJ1WyfHBvQcCTYBGC0dcsghaZ999knTTDNN/j0uaieddNJURlNOOWV+hEgSOOGEE6bRJanhp59+mn//6KOP8u/QiEan80kj68y58oMPPqhrgkzHBvQcwQoARkuTTTZZfhSiF0B7VllllfT666/nKRCjS+9ZZ52Vc0d0dirEzhgyZEi666670quvvprXIx7R5XmOOeZIN9xwQyqbWWaZJTfYJphggvz7fffdl37++ecu/Ywy1Avd57nnnkvnn39+euKJJ3IDM4IB888/f9poo43SOuusk8Yaa6zR4nxSVkcffXQ64IADOrUf11577fT000/nXgxHHHHESMt/8cUX6bTTTku33npr+vDDD9O4446bZpxxxtzLYbXVVkurr756GnvssbvlXBnHVa9evVK9NMKxAaMrwQoAGl70CohhDdVdequnJq2nN998M/3+979P119/ffrll19avR4X+WUUDY3qi/LpppuuoeqF7nX66aenfffdN+ciqPbkk0+mSy65JC2//PLp5ptvThNNNJGq6aQ///nP6d57702XXnppUw+RWi266KLppptuStdcc81IgxXPPPNMWmuttXLAqdorr7yS7rnnnnTqqafmZRx88MHdcq6cYYYZOvQ5wOhDzgoARktx922PPfbId2bjsffeezcNWWgp7tK9/fbbTV16o8dAd9y9j4v6xRZbLF177bW5EbbZZpulc889N1/QX3TRRaO07L322iv3flhggQXSyiuvnH7zm9+kyy67LN/lHF30VL3QvcdSBKTiMyJQsd9++6VHHnkkvfHGG+mll17KPWnmnHPOdP/99+eeNR0ROSWiR85SSy2VcxxEAzoa2/U+n5TVjTfemPft4osvnn92xMCBA/PPqJP4Hrbn66+/zr0wIlARAY7Y3y+//HJ+3H333emEE05IAwYM6HAvrHqeK0dVIxwbMNqqADBGueCCCyrLLbdcZe65566sssoqlXPPPbcyfPjwSll89dVXlZlmmqky11xztVvm008/rcwxxxyV+DNW/Yj3fPLJJ6P0+UsssURe1n/+85+m55577rmm5XdmWfPNN1/lgw8+aPbaPffck1+LMp2x5ZZbttr+4rHCCitULrvsssr3339f6Sorr7xyrpdnnnlmlPdLTxk2bFibx9both1d/Z2q97H0+uuv52VNNtlkbZ5r9thjj/z6AQcc0Ob7X3vttfz6bLPN1vTcnXfeWZl++unbXOedd965Q/U7KueTyy+/vNK/f/9cdsUVV6ycffbZlR9//LFbzzPVnn322bxfxhtvvMqVV15Z8/t+/vnnytRTT50//+9//3u75Y4//vhcZtFFFx3hdnb0eBnVc2Vb56da1PPYiL+tyy67bGXOOeesDBgwoHLGGWfUdGwA/yVYATAG+cMf/tDmxX1cSA0dOrRSBl988UVep7jYbs+ee+7ZdGF7//33Vx566KHKIosskp/bYYcdRunzu6oR8fHHHzft33/84x+tXh/VYMXnn39eeffdd/O6RcPt9NNPr6y77rqVSSaZpOlzZ5hhhtzwiAZiNEYiUBUNz85YYIEF8jIfe+yx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AEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVHr39AoAAAAA9fX222+n6667boRl9t5779SrV6/8/w8++CA9+OCD6Ysvvkizzz57WnbZZdPEE0/c6j21lusowYou8vPPP6dffvkljTPOOF21SAAAAOgSL730Utp3331HWGaPPfZIvXv3Tuuuu2668cYbU6VSaXptxhlnTBdccEFaddVVm56rtVxnGAYyioYPH57OP//8tOCCC6b33ntvVBcHAAAAXW6VVVbJvR/aeiyzzDJpsskmS2ON9X8hgv/85z9pxx13TI8++mhu51544YXps88+S5tuumn65ptvmpZZa7nOEKwYiY022ihtu+22rZ7/4Ycf0llnnZX69u2bbrrpptydZo455khdZbPNNmv2ubvssktab7310pjEPgAAAOga0WNi8sknb/V4/PHHc9Dhd7/7XVOw4pprrkl///vf05JLLplmmmmmtM0226Ttt98+BzYeeeSRpmXWWq5T6zvKW9zghg4d2uz3GOpx9tlnp6OOOirNN9986corr0z9+vWry+dGr43CsGHDWq1Lo7MPAAAA6uvggw9OU045Zdpnn32anltuueValZt22mlbPVdruc4QrOig6M4SPSkuv/zyPD6HETvssMPSq6++mrbYYou01157pcGDB9tlAAAAJXDDDTfkHhBHH310mnTSSUdYNpJoRs+LBRZYoEvKjYxgRQfdc889aeDAgQIVNfrjH/+Yk4+OO+646amnnurwAQoAAEDXi1EDhxxySJpmmmnSnnvuOcKyd955Z7r77rtzmoQZZphhlMvVQs6KDrriiivyzo9KYOTGH3/8NNFEE+VZUlpG6j7//PM8RurNN99Miy++eLrssstGeZcOGTIkvfDCC80er7/+uqoCAACoEqMFnnvuubT//vuPcKrRd955J2299dZ5eMff/va3US5XqzE2WHH77benpZZaKs0111zpyCOPbDbVysgyqEa3lkg+cs4553Tqs99444205pprpllnnTVPDfPTTz+lRnX99dfnQEQkH4199v333ze9NsUUU6S33norzTbbbOm+++7L0bdRdcYZZ+SZWaofY1piUgAAgBGJ/Ih/+ctf0vTTT5922223dsvFDea11lorffvtt+nmm2/O5UelXEeMkcNAIm/CoEGD8oweIbq+RBeYP//5zzW9PxJrPvDAA3m2ipii5fTTT889B2oRn7PBBhukZ555Jv8e75133nlz0KIrD7wYfhHJPyeZZJI8q8jvf//7NPbYY6d6idlKPv744xycKDz//PNp4403bkoU+te//jVv/ymnnJJ/79WrV+5ZEWI9u0J80eIzq0XPCgELAACA/3PeeefldtKpp56aJpxwwtSWL7/8Mq266qp5StLbbrstLbHEEqNUrqPGyJ4VTzzxRA5URMTntddey4GLI444Ij9fq5iD9l//+lf66quv0tprr91m74i2pj2NAyICFQceeGB6991306KLLpruv//+1NXZXE8++eR8sLz00kvpgAMOaDcY0t7UrIWLL74494D48ccfmw21iCBDHIgjmq3k1ltvzYlVohdLDPVYeeWV07XXXtvhdeiI6HIUiVyqH3369OmSZQMAAIzufvjhh9z+jalG46ZzWz755JPcfoue8HfccUdaeumlR6lcZzRksCIa6NGYfvjhh9t8PYIL66+/fo4mRRQpeiBEo3bnnXduFXSIXgHfffddm8uJngqxjHvvvTddddVVrV5///3386Pahx9+mH9GApOpp546Lz8OkpbiM2Me3I765ptvcm+NX/3qVzkQE49NNtkknXXWWc2CCyNax2rRWyIiZdWzeHz22Wc5SFMdnPj6669zl59qMbwjghXRBSi2MYIebW1re+vQ2X0AAABA+0Pn48b2QQcdlMYbb7xWr0d7L6YkjbZg3Fhfcskl21xOreU6qyGDFdFgj8Z0e7kgIkARd/jjjv4iiyyS3n777XTRRRelF198Me2www5NjfDY+TGDReRTePLJJ9tcVgQqotfB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DRgwoM3n99133/xzq622anruL3/5Szr33HNHuLwIRvz000/prrvuSvPOO29+bocddkj9+vVLRx55ZPrtb3+bJpxwwtRQw0Ciq0k00msV42M+++yzTr+/LBplO+rBvgEAAOha0YPirLPOSuuuu24OMhROPvnk9OGHH6Ybbrih3ffed999qU+fPk2BijDOOOOkbbfdNn355ZfpoYce6rL1LE2wgsZ0zDHH5HFSt912W1p44YV7enUAAADGaIcffnj64Ycf0mGHHdbs+UknnTRNP/30I0yq+csvv+T3tjTnnHPmn6+++uqYEayInRCZRZ999tmeXhU6affdd89jmaL7UQQsAAAA6BmDBw/OOSY23HDDtMgii3T4/UsssUR6++2307/+9a9mzw8ZMiT//Oabb8oVrHjwwQfTPPPMk7799tscXHjxxRe7YrE5l8PDDz+cs5Qyeoro3FRTTZXGH3/8NMMMMzR77YsvvsjHy1tvvZWWW265dNVVV/XYegIAADS6P//5z7l3ROSn6GzP+WjbxRCS5ZdfPq233np5SMguu+ySX++qfBVdlmBzySWXTPfcc0+aYIIJcnChrXlaOxMAiQSLMb/rwIED08Ybb9xmFtN6irE4vXr1ylOxRNQpsp7GukTG064oPya4/fbbc6KVCEysv/766ZBDDsljmkLslzheIogRgYoIbIyqiOi1zPkRxxAAAMCY7Pnnn09XXHFF2nTTTdMCCyzQqWUsu+yy6ZFHHknHH398eumll3LgY9CgQWnsscdOxx57bJpllll6LlgRXT5iBS+55JK0wgorNPWAmHHGGfP/4055LbbeeuvcOD399NPbDYBE8o4Q3VQmmmii1FVih8b4nCuvvDJNMskkORnIbrvtlgMNLROPxFCUaOxGopAzzzwzjTvuuDmK9Ic//CE3iqOCiulZOlq+I0a2vzqzfV2prVlMYlqbddZZJ/34449NX47vv/8+H9ghprYpjpcYG9UVzjjjjFZjrwAAAMZ0Bx98cG4THnrooaO0nIUWWihdfPHFzZ7beeedm9rxPRas+Pjjj9P7778/wqQb1VZfffW8wnF3vVo0bGPKk/ZEAGSmmWbKjfToSlJM7dkVojEbSUUKjz32WHrjjTfSSSed1Go8Twxtidk64hGZUZ955pncC6AYshCBgM6W74iR7a/ObF8Y2f6N4EPMmRvvL3pE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wQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKpXdPrwB0l3/u0T8tssgidvhoavjw4enLL79Mk08+eerd26lrdKYuG4e6bBzqsnGoy8agHhuHuuw8PSsAAACAUhGsAAAAAEpFsAIAAAAoFcEKAAAAoFQEKwAAAIBSEawAAAAASkWwAgAAACgVwQoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKBXBCgAAAKBUBCsAAACAUhGsAAAAAEqld0+vANTbDz/8kH++/vrrqXdvh/zoavjw4embb75Jk0wyiXoczanLxqEuG4e6bBzqsjGox8ahLv8r2mPV7bOR0XKj4T333HP550YbbdTTqwIAADBGe/fdd9Piiy8+0nKCFTS8vn375p9XXnllmn/++Xt6dRiFSOx6662Xrr/++tSnTx/7cTSmLhuHumwc6rJxqMvGoB4bh7r8r+hREYGKAQMGpFoIVtDwJp100vwzAhULLLBAT68OoygCFeqxMajLxqEuG4e6bBzqsjGox8ahLv9PLT0qChJsAgAAAKUiWAEAAACUimAFAAAAUCqCFTS8aaaZJh166KH5J6Mv9dg41GXjUJeNQ102DnXZGNRj41CXnderUqlURuH9AAAAAF1KzwoAAACgVAQrAAAAgFIRrAAAAABKRbACAAAAKJXePb0CUC8///xz+te//pWefvrpNNFEE6W11lorzT///HZ4SV122WW5zrbeeutWrw0dOjRde+21afDgwWnaaadN66+/fppxxhk7XIb6ibq777770qOPPpp/X3DBBfN3bqyxmsfEP/roo3Tdddfln3PMMUfacMMN0ySTTNLhMtTPsGHD0u23356ee+65NO6446b55psvrb322mnsscduVu7ll19ON910U/7uLbTQQmnQoEGpd+/eHS5D9/jpp5/SMccck6aeeuq02267NXvtoYceSvfee2/65ZdfUv/+/dMKK6zQ6v21lKE+Xn311XTeeee1+doqq6ySHyHqprjumWCCCdKaa66Zz8XVailD9/3NfOKJJ9JXX32VllpqqXx+LHz77bf5mub111/P39n11lsvzTzzzM2WUUsZ6iPq7aqrrmr39fheDRgwIP//448/ztc0H374YZp99tnzNc2kk07arHwtZcZUelbQkL7//vv8x3uPPfZIP/74Y3rppZfSoosums4+++yeXjXaEH9wDzzwwHTNNde0eu29997LjZxTTz019erVK91yyy1p3nnnTQ888ECHylDf+ougQgSI3nnnnfTJJ5+k7bffPv3617/ODd/qxs4888yT/vnPf+Z6Ov300/NFcrynI2WonyeffDLNMMMMaZ999klff/11+uCDD9IOO+yQv19DhgxpKnfuueemhRdeOAc0ohG87777ppVWWil99913HSpD99l1113zNN4XXXRRs+ejXlZbbbV8sfzFF1+kddddN+28884dLkP9vPHGG+m4447Lf+smn3zyZo/xxx8/l/nhhx9yHUUgKv7/yiuvpMUXXzydccYZTcuppQz198wzz6RFFlkkf6/ef//9NPHEEzd7PQL1cc16wgknpJi08Y477sjXNHfddVeHylA/Echv+V2MR4jv6iOPPJL/Hz/jmiYCEXFNc9ZZZ6UFFlggvfXWW03LqqXMGC2mLoVGc9xxx1XGHnvsyquvvtr03EEHHVQZb7zxKh988EGPrhv/NWTIkMquu+5amWuuuWIK5cq6667bavdsvPHGlZlmmqny7bffNj23+uqrV/r06VP5+eefay5D/XzxxReVhRZaqPL+++83Pffkk0/mOj344IPz77/88kulb9++lZVWWqmpzHfffVeZbbbZKhtssEHNZaivW265pbLeeutVhg0b1vTcvffem+vygAMOyL9/9NFHlQkmmKCy//77N5UZPHhwpXfv3pWjjz665jJ0n+OPPz7//Ztiiikqv/rVr5qev++++3LdXnbZZU3P3Xjjjfm5m2++ueYy1P97Gfv7qquuarfMSSedVBlrrLEqL730UtNzhx56aGXcccetvPvuuzWXob7iGnSqqaaq7L333pXh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8Zumlq6lDPW1++6756m4n3322abnDjzwwDwV6eDBg5vOw1NNNVWzaSvXXHPNyhxzzFH56aefai5D/cU0pfF3rai7lhZbbLHK0ksv3XRNM2zYsMqss85aWX/99TtUZkwmWEFD+vHHHysDBw6sTDPNNPkPw0YbbZQbUhdddFFPrxpVhgwZUvnjH/+YHxNNNFFl7rnnzv8/9thjm8pEcGm++ebLgYe99967svzyy+c/0I888kiHylA/N954Y2649O/fv6k+qx8vvPBCLvf4449Xpp566hyMiHqaf/75c51VXyTXUob6BnrjQnreeefN58711lsvX4jts88+zcpFACMaOPH6HnvsUZl++ukrq6++euX777/vUBl6NlgRDjnkkFxP2267bWXHHXfM5+KW9V1LGepnueWWq0wxxRSVTTbZJAcAI6gb1zf3339/U5looA4aNCifP3fbbbcc4I3rnvPPP79DZaivCC7F9emUU05Z2XnnnfP/47sV58tCBHujjvv06ZP/Dq644oq5/h988MEOlaG+4tombozGObE9Tz31VGXaaaetLLPMMvmcueCCC+Zr3XfffbdDZcZkveKfMb57CQ0pDu177703z1EcyYxiCr7ZZputp1eLKp9//nn63//931b7JKZR++1vf9v0e4zpu+WWW9Kbb76Zc5IMHDgwTTHFFM3eU0sZ6iO6EcdUbO3ZcMMNc/fWYlxmDBUZMmRImn322dOaa67ZakhALWWonxhPG0k1I2lYnDsj90gM3WgpEjVGQrjIBRRdVVdcccVWs07UUobuc/755+euxdFludpzzz2X7r///vx389e//nWb3chrKUN9xBCBhx56KA0ePDifH2eZZZZ8XozZeVqK654YzhXDDeK6J86hnSlDfcU59umnn06TTjpprssiv0F1nrVbb70113nkuogpiCPvSEfLUD/xPXr44YdzYs34TrYn8nHFNU3MBhPftainltc0tZQZUwlWAAAAAKUiwSYAAABQKoIVAAAAQKkIVgAAAAClIlgBAAAAlIpgBQAAAFAqghUAAABAqQhWAAAAAKUiWAEAAACUimAFAEALH330UXrvvfdq3i+ff/55euutt1KlUum2ffnVV1/lzxw+fHiPrgcA1INgBQBAC5tttlnq379/zfvl8MMPT3PMMUcaNmxYt+3LM888M39mBCd6cj0AoB4EKwAAAIBSEawAAAAASkWwAgCgjr777rs8VOOnn35Kn3zySfrwww/tbwAYCcEKAGCM8f3336ePP/44/fLLL932mY8++mhaYYUV0ptvvplzSuy2227d9tkAMLoSrAAAGt51112XllpqqTTBBBOk6aefPk000URpgw02SIMHD677Zw8YMCD3rOjbt2/629/+ltelLCKAUquYdSS2I2ZKqcWnn36ay1bPVgIAtRKsAAAa2hVXXJEDE4899liabLLJ0kwzzZTGGmuspgDGF198UfOyvvnmmw6Vr/bll1/W1HAfOnRopz+jo6Knx3bbbVfT7CE///xzWnjhhdMiiyzSbs+UmDL1tNNOS7PNNluaZppp0gwzzJAmnnjitPzyy6eLL764DlsAQKMSrAAAGtrDDz+cf9588805YPDee+/loEMMx/j8889r6l1w1VVXpSWWWCJNOumkacopp0z9+vXLwztq8fjjj6cFF1wwTTHFFGmSSSZJv/vd73L+ipZ+/PHH9Nvf/jZNPvnk+TMiMPDQQw+leppxxhnThRdemIM2r7zyygjLjjfeeGmNNdZIQ4YMaXfbDzzwwLTnnnumd955J0044YQ5WBGBjQceeCDtvPPOddoKABqRYAUA0NDWXXfd/PPuu+/OAYFw6623phtuuCHNPvvsaaGFFmr3vV999VVab7310iabbJKefPLJHGyIoSRPPPFEWnnlldNrr702ws+O96+zzjrphRdeyMGK6J3w17/+NfdoaCmeP+uss/L/o+xzzz2XVl999fTSSy+lejnqqKPSOeeck95+++209NJLp3//+98jLL/++uvnnzfeeGOr12LIx4knnpjX/ZZbbsm9NT744IMcGLrzzjvThhtuWLftAKDxCFYAAA1txRVXTIceemhuSM8111x5GMPAgQPTDz/8kK688so0zjjjtPm+aGzH8IUIakQvgTPPPDP3xIgAxP7775+Ha5x88skj/Oy77rorN+L322+/9Nlnn+WcD7PMMku64IILWpWN56KnQ5SJz7nkkkvyZ8R762nHHXfMvU8iyBA9J5599tl2y8Z+G3fccdO//vWvVq89/fTTORhzyCGH5OVU98iIwM6ll15at20AoPEIVgAADS8a0BG0iCEg0Rjfeuut0zPPPJOWXHLJESaIjLIRQHjkkUfSrrvumnr37p2DG8cdd1xO1BkN9BDPh5bDO7799tv8Mz67V69eeVnRkyOCEC3LvfrqqzkZ58wzz5yf23LLLXOwJHopxOe3NbNJaC/Y0hExTOXee+/NQ1Bi30TuibbEMJiY2ST2yxtvvNHstemmm67L1gcABCsAgIYWAYrIyXDPPfc0PRfBhUgAOTIRkLjvvvtyY75lIOO7777LCTtD9JYIEQCpFsM4pp122hzouOOOO/Lwjwg+bLHFFs3KxfCLyO3w1FNPNUteWQQudt9991bJOSNQMvbYY+cASFeYddZZcx6PCES8/vrr7ZZbfPHF88/o+VFtscUWy8GVY445ps3hMbHPYigOANTi/24DAAA0qOgpEPkmVlpppfSXv/wlnXLKKen888/Pjf0DDjggDwuJoQox7COmNI3hGpFsMnpCRB6JCGxE4/vrr7/OgY8YMhFDNmI4yPbbb58/o3///vlnNPbPO++8vLwYVhE9FI444ogcbFhttdVymT59+qRtt902D/f45JNPctBj3333za+9/PLLeVjGPvvskz/z+uuvz+sUOTI23njjtNdee+XgxD//+c+cNyISfXamJ0P0yqiegjQCIdGzI5Jtxkwp0Usitq96VpLI9xGBjIsuuij/ftJJJ+VeIpH3I7Y1xLCYWP8IXGyzzTY5mBM5N2JfR16M+D2SnALAyPSqtNfPDwBgNDd48OAcHBg0aFBu+EcAIkRSyT322CPnrSjEEIhaG9LRo+Gggw5Khx12WLPkk/EZYfzxx28aplGIoEMM96i+9IrlRJ6HEIk4o2dGzKRR7fLLL8+5NWKq1WoRVIjeGhGEKUSQ49RTT81JLWPK0PZEwstVV121zddiGRGkOfLII/PwmZYieBNBiugF0t62tiX277LLLttmvgsAaEnPCgCgYRW9B2JGkCJQEXbaaae03HLLpeOPPz7ng4gcEtH4L4Z1tBTvjVlAZppppjxrRvTW6Nu3b7MykUAyZteIKVLff//93DshGvbREyICEbvsskv68MMPc6LOBx98MPfgiMd8882XE1JG8CN6M0QAJIaeRH6I6JGx2Wab5fWPpJ7RIySGpkSi0Ei8WR2oCDHl6WyzzZa3ZURiW6JcIZJmxjLjs6JHRBFcqC4TPTjmn3/+PD3poosumvdd9PCI4EqsU+yjeETwonhv7KMIbET5Oeecs1kdAMCI6FkBADSsjz/+OAcL1l577WY9K1qKHhYxdAMAKAfBCgCgoW2++ebpiiuuSMsss0z67W9/m3sHRK+FyBcRORhiSET0rLj11lt7elUBgP9PsAIAaGiRvyHySdx1113tlllllVVy/gcAoBwEKwCAhhdJLSNB5VVXXZVeeOGFPANH5HeIfBEDBgxIG220UZpkkkl6ejUBgP9PsAIAAAAolRGnigYAAADoZoIVAAAAQKkIVgAAAAClIlgBAAAAlIpgBQAAAFAqghUAAABAqQhWAAAAAKUiWAEAAACUimAFAAAAUCqCFQAAAECpCFYAAAAAqUz+Hx+r5vrDHsCvAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1080x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "تم حفظ الرسم: saudi_labor_law_voice_agent_project\\05_reports\\figures\\03_ar_chunking_strategy_comparison.png\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>نوع التقييم</th>\n",
       "      <th>العدد</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>تقييم الأسئلة الشائعة</td>\n",
       "      <td>199</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>تقييم المواد القانونية</td>\n",
       "      <td>24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>أسئلة خارج النطاق</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              نوع التقييم  العدد\n",
       "0   تقييم الأسئلة الشائعة    199\n",
       "1  تقييم المواد القانونية     24\n",
       "2       أسئلة خارج النطاق     15"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKMAAAHUCAYAAADm5evPAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAAVWVJREFUeJzt3QeUVOX5B+APRUEURRELKnZRLGjssaAmGns31hhrFMUae+/daJRYYom9F2KJJvbee1dsiL2A2ACB+Z/3+5/Zs7vsLrOw3N0dnuechd2Ze2fuvd/M7sxv3u+9HUqlUikBAAAAQAGmKuJOAAAAACAIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAA2ok99tgjrbHGGunNN9+suezDDz/Ml22//fatum20b59//nnad99906BBg1p7UwCYAnRs7Q0AAKAyL7zwQv4aMWJEzWU//fRTeuSRR9KCCy7oMNJsX331VTrttNPSRRddlH755Zf029/+1lEEYLITRgEAwBTmm2++SWeccUb6xz/+kX7++efUqVOntNdee6Xf/e53rb1pAEwBTNMDAJiCnXDCCXma35AhQ9K9996bv7/99ttbe7OYTL777rt05JFHpvnnnz+deeaZacyYMal///5p8ODBOZjq0aOHYw/AZCeMAgBoYRdeeGEOdcrT6uL7f/7zn23yOEf/qZjmF9UxX3zxRf7+008/be3NooWVSqV0/vnn5+mcp5xySho9enTac889cwh1wQUXpLnnntsxB6AwwigAgBb2/vvv51Bn2LBh+Su+/+CDD9rkcT7mmGPSQw89lHr16pXWXXfd/P1mm23W2ptFC/vLX/6SG5RHv7Hdd989h1ARms4zzzwTfZsRXkbQetRRR+Wfd9xxx7Teeuu14FYDUK30jAIAaGEx7WnDDTdMffv2zT+Xw562qE+fPvkrdOnSJc0xxxytvUm0sAiNLr300vz9jTfemLbccssWud2RI0fmoLVbt27552effTYNHTq0RW4bgOomjAIAaGExFar22e2ieqQxO++8c+7X9MADD+RKlQgLzj333LT00ksXNi5jx45NL774Ynr33XfTRx99lL++/fbb1LNnzzRw4MAm17vppptyr6nPP/88TTvttHmdpZZaKq2zzjppkUUWKWwfaNz000+fZphhhvTjjz+m8847L6299tpppplmmuRDFsFlBK2zzjpr/vmqq65Ko0aNMhQATJAwCgCgFT333HPp7bffrjO9b/jw4YXc9/fff5/7B1122WU5fKpv2WWXbXTdqIDZeOON00svvdToMhF87LPPPi22vUycrl275tBw8803T4899lhaZZVV0h133JEWWGCBSTqknTt3rhO0rrDCCoYIgIoIowAAWlhMX7rooovSgw8+mH+OSpTo2dOpU6fxlv3Xv/6Vm4fXnt5XRFXUJ598kvr165c+/PDD1KFDh7Tccsvl7YyA4ptvvkmHH354o+tG9cv666+fXnvttVwdc8ABB6TFF188X/fZZ5/lpu333HNPgwFXXHb66afndXv37p3XnXfeeVt0304++eR0//33pxlnnDFvX1SpRWgS4drUU0+dpkTRy+nRRx9NW2yxRXrjjTfS8ssvn26++ea01lprtfamATAFEkYBAFXn8ccfT5dffnnulRNBx7bbbptWX331Qu77l19+SWuuuWZ65plnai6788470/XXX58DkujLVFuEAo1N75ucdtlllxxEzTnnnOnuu+9OyyyzTM11Dz/8cJPrXnnllTlMmm+++fL0vplnnrnO9dEge9y4cemrr76qc3mcpW/VVVfN0wBDTO+77rrrcjXYYost1uj9Pf300+niiy/OUwGj99Y222zTZIjy1ltvNbgPEU798Y9/zMFg7eM+IXFbV1xxRb7/aPi99dZb5+CuvYl9jqAwtj+m1/3hD39I55xzThowYECL3H5MOY3HVIxVBI0A0KgSAEAV+cc//lHq0KFDKV7m1P7685//XBozZsxkv/9jjjkm39/ss89euvzyy0tXXXVVae65586XHXTQQZN028suu2y+naeeeqrmstdeey1ftuCCC1Z8O99++23NcYltrO+hhx7K18X9NWT99dfP11922WXN2v511103r7fccsuVbr311tJ2221X83NjrrzyylLHjh3HG89dd9210fF888038z7cfvvtpYsuuqh0wAEHlBZffPE66y+//PJ5mbLHHnusdM8994x3W//6178afDxts802pV9//bVZ+x/r9OvXr/TSSy+VWlMctzgm5X058sgjW+R2y8f4ueeea5HbA6B6CaMAgKrxxhtvlKaZZpr8hni33XYr3XnnnaWBAweWZpxxxnzZEUccMdm3YaGFFsr3dffdd9dc9uijj+bLZptttjYRRr377rs1QcTDDz883vX/+9//mgyjyqHD008/XfF9vv/++3mdaaedtjR06NB8WYQ5sd1xeUNB0LBhw0rdunXL1//lL38p3XHHHaVzzjmnNNNMM+XLTjzxxFJzfPTRR6Wjjz66NOuss9bs/0YbbVTaeOON8/dnnnlmneW/+eabmsdOPJ7i/ms/ng455JBm3X/5sfn555+X2oLzzjuv5jjceOONk3x7wigAKiWMAgCqxo477pjfWK+55pp1Ln/ggQfy5REGRBDTmJ122ilXrkSoNbHLlAOHqD6qXYlSrq75+eefJ/q+y2FU7RBoYsKoX375pdS5c+e83s4771waO3Zsvjy27Z///Geu6moqjFp55ZXz9dddd13F9zlo0KC8Tt++fetcftxxx+XLY/8bW2ettdaqc/mDDz6YL+/UqVPpww8/LDXXiBEjcmVV7Uqn3/zmN/lY1hbVW3HdGmus0eDjKY5h3FYlRo0aVXNfE1uhF+Mej5E99tij0WUqeRzVtt9+++VtWmKJJZpc7qyzzsq3279//0aXWWyxxfJtvfDCCxXdNwBTrqkan8AHANB+jBkzJt1+++35+0UWWaTOddFfaNFFF02//vprOuKII5rsTRT9i4YNGzbRy0QPpnDbbbfVXBa9keJDwG7duuUzkE3sfZevm2GGGdKkiG3Ye++9axqoR9Py6CfUo0eP3E/pu+++y9eNGDGiwfXjbGzhjDPOyMe9IdEE/dRTT0177rlnTb+m8hn8altttdVq+nzV9+yzz+b/F1544TqXR0+u6DEVjdRPOOGEZu173H/0SSqPz9xzz50uvfTSfFbDJZZYos6y0V8p9OnTp8HHUzSqj/UqMe2006aZZpopfx/9tiZGNF+Px8j//ve/Rpep5HFU29FHH50b2L/++uu531lj4kx8Tz31VLrwwgtzA/SGfPnll3XGGgAaI4wCAKpChAI//PBDnRCjttlmmy3/f8stt6QHHnhgvOsjqBoyZEj+/p133mnwPipZ5pBDDsn/R9hz0003pfvuuy9tt912+bL9998/v/GfmNuNN/qxTAQS888/f5pUp512Wtpvv/3SNNNMkz7++OP0/PPP52Bphx12yA3NQzQa//rrr8dbN9aLwOHll19Om266aRo+fHi+PAK3OLZxGxHyRPA3dOjQfN1SSy2Vtz1uc9CgQTW3tdBCC+X/o/F1/WArmmyHCEHitmuL4CxEY/FoDD8hESztscceebuOPfbYHNZEI/T33nsv7brrrmmqqcZ/WfzYY49N8PHUVIBTXzQMLz8Ofvrpp9Rc77//fs2ZEBtav5LHUX3TTz993vf46tix8XMbxWNuo402yt/H2RDre/vtt3OIGUFnNLYHgCa1dmkWAEBLiH4/taddnXzyyTXXPfPMM3lKV3mqXo8ePUrvvPNOzfUxTe3AAw+sWTemvEV/odoqWSaMGzeuTnPo8tfWW29dGj169HjLV3K7Ma0r1o/r11577TrXTcw0vdqGDx+ee1DF1KqffvqpZh8WWGCBfLs77LBD/rm+//73vzW9k6KH05Zbblmac845a/Zj+umnz32eXn/99Zp1ylPjYnrb2WefXfr+++/zfZbXqT218dJLL61z/KLJdnk7nn322ZrxjObm0Yvr1VdfHW8cXnnlldIpp5ySpwaWb2eRRRYpbbjhhvn7Xr16lYYMGdLgcYnG87Xv/6STTmrw8dScaYJvv/12qUuXLjXjdfHFF1fcPyqasi+88MI12xPT5WpP96v08Vlb9Ow67LDD8vIrrrjiBLfhkksuyctONdVUeQpj7Wmf5eb0W2yxRUX7A8CUrUP803RcBQDQ9kXVSVSyxNSwqDwJc801V5p99tnTq6++mqtutt1229S3b9902GGHpemmmy5XBS299NK5Oubzzz+vc3udOnXK07NiWldU00xomXnmmSdfFlO3Bg8enL799ts6y84888xp3nnnzRVF8fIrqki6d+9e0X3H7X322Wd5qtcTTzyRlltuuZplY3rVkksumRZccMG8XEuJqYUbbrhhGjt2bN6GqDrr3bt3Pm5ln3766Xj3ueyyy6bddtstbb/99qlr1651rotqnk022aSmMi32Jyqj3nzzzfzziiuumG9vlllmyccl/P73v8/LxzGLKZDxVR7PuI8Yz6hGi7GMbVtmmWXy/cT65SmBUZG1zjrrpL322ittsMEGeQphTP2L62OdqNqKip5x48ald999N49R+f7XXnvtXN0WGrr/a665plnH9cknn0xbbbVVHs/aVV5xjLt06TJedVIc/y+++CJ98MEHefvqV2fF4y2OYTyGKnl8lo0ePTof66h8i2q9u+66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P/30afPNN0/vv//+RC/XEoRR7Vg8KPbaa680cODANHbs2NbeHAAAAKDAmVIPPvhgOumkkxpd5pJLLkkbbLBBGjVqVDr00EPTNttsk+666660yiqr1AmvKl2upXRs8VukMG+99Va677770nXXXZeefvrpNOusszr6AAAAMAXo2bNnDo8aM3z48PTXv/419enTJ7344otp2mmnzZdvtdVWab311kunnnpq+vvf/17xclVdGfXll1+mzz77bLLd/ueff14n1Wvp+6t/+5PThRdemAYPHpy/6gdRpVIpX/7TTz8VclwBAACA4jz66KPpqaeeSptttlmD1z/xxBPphx9+SFtuuWVNwBTWXXfdtNhii6VBgwY1a7k2EUZ9/fXX6auvvsobPCkNtOs34I40bscdd0yTy+67754GDBjQ7PurdH+jf1Pt25+c4thF4NRQc7EIoRZeeOF0zz33FHJcAQAAgOKssMIKaaWVVkqzzTZbg9eXm5pPPfXU410XIVNkGz/++GPFy7WJMOr8889PZ599dp4mNrENtP/973/nBtwREE2KCGMilPn111/T5NIS+9vS3njjjRw4XX311am9+Pbbb3PlWIRlH374YWtvDgAAAFSlxRdfPP9/++23p19++aXOdeWilhEjRlS8XJvoGXXCCSfUfB8d1ie2Afc+++yT/vjHP+YdnGqqicvGvv/++1w+9r///S8tsMACaXKY1P39+eef8xS++eeff6L3s77VVlstrbXWWnnbtt9++9SxY9tvAfavf/0rj/sWW2yRjjjiiPTss8/WXPfBBx+kOeecM1d8denSJc0888ytuq0AAADQXi266KK5EfkNN9yQlllmmbTOOuvkKqgnn3wyF7eETp06VbxcS2qR9CKCpKh4ibmFM800U8Xrvf3227nze1T2PPfccxMVPkSFTTTbisqoKB2LaXRdu3ZNk1Nz9zfCl+hAP8MMM6SXXnqpRbfv+OOPz6FUhDyTWmFWhIMOOqjm+9///vd1rttoo43S5Zdfns4777x8vOJMgY2JKZMxdbK2eAwAAAAA/++qq67KU+3ixGfx/VxzzZV7TEWRTLyHLucwlS7XUia6ROe2225Lm266aZ4m1qtXrzTHHHPkhtoN+eabb3JVUP3eRv/85z9rGnBP7I5Fs66tt946fx9hTEyjmxyas7/1xb6vueaa6dZbb21wDuak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8pHKKKYke+65Z668uuaaaypaPpq3R6VTiKqw8hkSG7scAAAAILTtSYcUJhqGxxTB2WabraLljzzyyDx9L0Sfq2jm3tTlAAAAAEEYRXbJJZc060hET6zmXA4AAAAQpnIYAAAAACiKMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwnQs7q6gGHcMWDX17dvX4a4iY8aMScOHD0/dunVLHTv6tVVNjG31MrbVy9hWN+NbvYxt9TK2tEcqowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMIIowAAAAAojDAKAAAAgMJ0LO6uoBgbD3w8deg+1OFuxz46bYPW3gQAAAAmE5VRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAUAAABAYYRRAAAAABRGGAVUhdGjR6eRI0dWvPyYMWPSN99806x1AAAAmHTCKKDd+uWXX9Ipp5ySlllmmTTddNOlLl26pPnmmy+de+65aezYsY2uVyqV0tZbb5169OiRLr300kK3GQAAYEonjALarffffz8deeSRuSrqiCOOSCeccEIOpQ444IB8eWOOOeaYdNtttxW6rQAAAEyBYdThhx+edt9994lad++9904HHnhgi9xWS95GkdsLbc0000yTzjrrrPT666+nE088MR111FHpqaeeSt27d08XXHBBGjdu3Hjr3HDDDemkk05K2267batsMwAAwJSuY1F3FG8UR40alZZffvl08cUXp//85z+paJ988kn64osvJmrdjz/+OHXu3LlFbqslb6PI7YW2pnfv3vmrtm7duqWllloqPfTQQ+nnn39OM8wwQ811zz//fNpll11y5dT666+frr/++lbYagAAgClbYWHUrrvumvu0TD/99KlPnz6pLYn+Mh9++GHaZJNN0rHHHpsee+yx1t6kquVYU4SPPvooV0fVDqI+++yz/Bzv169fOvPMM3NYBQAAQBWHUT179qxTudAcl112WXrkkUfSVVddNVnWiek6UbU188wzp0suuSS1pJgmNNVUU9RsyIk+1ssuu2y66KKL8vSqlVdeOf3lL39pte2k/br77rtzuLzHHnvUaXQeQdSMM86Yp+lNPfXUrbqNAAAAU7LCwqjhw4enQYMGpVdffTVPIYspY7vttlvaeeedJ7huvIlca621mnV/zVln9tlnr/l+0UUXTS3pj3/8Y+5P09K32141dayvvvrqNO+88+bm0rUrWqBSX331VQ4xoyoqqhzLYmpeNDt/5pln0kwzzeSAAgAAtKJCSnZuvvnmNP/88+dKpRVXXDEddNBB6bXXXktffvllRevPOuusef3avv766/TnP/85/fa3v23w1OwNrdOYaHi88cYbp9VWWy397W9/a7Dp8cSKfd10003T7bffPsFlJ7RP1aCpYx3TN2MaZ4xbjx49Jhg6vPHGG3W+Bg8eXMAe0FZFf6iNNtooffvtt/l3zpxzzpkv//HHH3M11CKLLJL+/ve/pwEDBuSvgQMH5utj2eghBQAAQJVURn3++edphx12yNVBBx98cM3lzZ26tueee6auXbvmXi8RYPzhD39IL730Uk3AEZU022yzTaPrNCam8/zud7/L03jC448/nkaMGJGOO+641BJWWmmldP/996d1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FEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFEYYBQAAAEBhhFEAAAAAFKZjcXcFxbhjwKqpb9++DjcAAAC0QSqjAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwnQs7q6gGBsPfDx16D7U4a7no9M2cEwAAABodSqjAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAACiMMAoAAACAwgijAAAAAChMx+LuCiasVCqlww8/PD355JPpkksuSb1793bYWtmXX36Zxo4dm3r27DnedV988UX68ccfG1xvlllmyV8AAABQmzCKNmXIkCHpqaeeSieddFKaa665WntzSCltuummafrpp0/333//eMdjzz33TP/+978bPE7HHntsOu644xxDAAAA6hBG0aYMHjw4Pf/882mvvfbKYcZWW23V2ps0RYpqpzfeeCPdfPPN6emnn06/+93vmlz+yiuvTFNNVXfW71JLLTWZtxIAAID2SBhFm9K3b9/03//+N3+/wAILtPbmTLHuvffeZgWB2223XerY0a8TAAAAqrCB+f/+97+0zTbbpE8//TStuuqq6bvvvmvtTaIFzTrrrHlc46uhHkUUY4MNNkiffPJJ/urSpYvDDgAAwJQbRi2zzDLp4IMPTt27d0+nnXZa6tq1a53rTzzxxHTAAQeMt956662XpxxNqkMPPTQdffTRE7y/llTEfTTloIMOqrPPk1tr7y8pTTfddGnuuefOXx06dJjgIYlw+KOPPko//fSTwwcAAECT2t28mh49euSvENUz9b3zzjv5DF/1RVPsP/zhD5N8/9FHp3PnzhO8v5Y0ue7jrLPOSqNHj84BX/T8ueGGGxpc7vXXX08zzDBDKkoRx5SWNd988+X/I7haffXV0z/+8Y+0+OKLO8wAAAC0/zAqvPvuu+mEE05Iv/76a67YWWKJJVp7k9qlzTbbLI0bNy7NNNNMabbZZmvtzaEdiufewgsvnBZccME0ZsyY9Oijj6ZbbrklrbHGGunNN9+sCY4BAACg3YZR33zzTVpllVXy/+GBBx7IlTtzzDFHmlLtscceac0118y9tJojAoSy5oZRI0eOTPvuu29666230j333FNo5VT46quv0tdffz3emfgo1kknnVTn5wEDBqRDDjkknXnmmbnSbp999jEkAAAAtO+eURdddFH6/vvv08UXX5ynAo0YMSKde+65LX4/cSr7559/vkVu68knn8yVIltvvXU6/fTT04svvpha0t57751WW221Zq/3yy+/pEGDBuUqs1133TU3rb7uuusqWveJJ55IP/zwQzr11FNzf6GiXXDBBbkqp/bXpptuWvh2kBrszxaihxQAAAC0+zAqql/mnXfetPPOO6e99tor7bTTTunOO+9s1m3E9L4IMzbaaKO0yy67NBg6RRPtmH7UEuKMf4888ki66aab0mGHHZaWXXbZHJ5ceumleWrTxIZla6+9dtp+++3Tvffemz7++OM85a5Ssc7888+fe0XNPvvsacstt8xTrIYMGVLR+nGWtdtvvz1XvjzzzDOpaDH2URFX+yuCNYoT/cYaq1ornxkRAAAA2v00vXKz7V69euUzfcU0sVGjRqWxY8emqaeeeoLrDx06NG2yySZ1qpOuvvrqPNXs97//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uC6++OINXv/tt9+mDz/8MM0666xpvvnmm+hlKN4XX3yRPv7447Tiiis2eP2nn36a/87OM888dX43h++//z699tprDa7Xq1ev/EXrKf+uXX755VOnTp1qLh87dmx66qmnGlxn5plnrvM8HzNmTHrrrbfyOosttlid26F1PfHEE2nRRRdN3bt3r7ksfsfGc7YxSyyxRH499cILL6RffvllvOunmWaaRn8XMPmNHTs2vf322/n/eM3bpUuXBpeLMf7ss8/y7+U55phjopdpi5xNj3bvjDPOSMcdd1x+U/vNN9/kQOKmm25KSy+9dGtvGs3w17/+NV1xxRVp2mmnzX9o33333bT33nuns846K7+pDXvuuWe6+OKL0yqrrDLe+rGu8KJtuvTSS9Puu++ellpqqdS1a9c61x122GFpww03zN8fcsgh6fzzz88vgIcOHZrmmmuudMsttwgr2rDNN988ffXVV+NdHi+Q441rfFDw8ssv57B4gQUWyOFTbZtuumk66KCDCtxiKrH66qvnF8X33ntvncvjBfNee+2VrrrqqtSnT588zvF//M3t2bNnxcvQeg488MA8NvF6qbbbb789HX300emDDz5IiyyySP4AYbnllst/W+eff/68zP3335/WXnvt/KFfhIy1/fnPf86/52k91113Xdp+++3zc652ABwf8kToFH9T6wfDK620Un6dFe655560884759fREVLEB0kXXnhh2mabbQrfF+qK18TxvLv55pvTlltuWXP5eeedl3+31vfDDz+kV199NY/puuuum18ff/3112nJJZess1wEVXfddZfDXbBSqZQGDBiQn7Pxt3ammWbKH7jH7+dTTjmlpqgiXkdtu+226fHHH8+/lyO4Wm+99fLv8Ommm67iZdq0ErRjgwYNKsXD+Kabbso///rrr6UNNtigNM8885RGjhzZ2ptHM3Tt2rV04YUXlsaOHVtnbE877bSaZfbYY498WYwz7ccll1ySx+2pp55qdJmLLrqo1KFDh9LDDz+cf/75559LK620Uqlv376lcePGFbi1TKp4fi644IJ5/MJLL72Ux//88893cNuw+Jt51113lfr375/H6w9/+MN4y5x00kmlaaedtvTyyy/nn4cPH15abLHFSmuuuWazlqF4Dz74YB6bTp06lbp37z7e9dtvv31p2223LX377bf5588//zy/llp++eVrlrnvvvvyY+P6668vdNtp2osvvli64IILSnPOOWcenw8//LDO9cOGDcuX//Wvf230NoYMGVKabrrpSvvtt1/NZSeeeGKpY8eOpTfeeMMQtJL333+/dM0115SWXnrpPIY333xzResdeOCBeezKj4X4m9yvX7/JvLU053VS586dS//6179qXuNee+21eYwHDhxYs9w222xT6tmzZ/59HD744INSt27dSvvss0+zlmnL9IyiXRs4cGCuiNpqq63yzx07dkyHHnpo+uSTT9KgQYNae/Nohkjwo/Jpqqn+/9fSJptskj+NjU9rmTKey6uuumrq169f/jk+zYlPiF555ZX06KOPtvbm0Qz/+te/8id8xx57rOPWjgwbNiydeuqp+dP0hqbmxCe5F1xwQdpggw1S375982Xxae4+++yTHnroofTGG29UtAyt4+yzz85VEjPMMEOD18frqGuvvTbNMsss+eeY5hEVMTEVNypVabti3OIrKssn1uWXX56ncR1++OF1KtbjdXVUR9E6HnjggXz8Y/pkpWKabawT1YqmSLdNUfkUFW077bRTTRXUdtttl3r06FHzvicq2WKZXXfdtWbaXbwviuVixkE8XytZpq0TRtFuxYvemANffzpe+ecoV6T9iOk69cV0jxEjRox3+fPPP5+eeeaZJufJ0/ZE6fDTTz+dp3/E87csxvj111/3XK4C0e/tpJNOyr2iYmpAbfGGNn5nRyDx66+/tto20rB4IRt/N+OroX4TMfUn+lE09Te3kmVoHTEVJ47/Gmus0eD18QFQ/X6b8Tc41P87HOMcz+VybyFaV0yzi7GND/SaEm9cY9ziQ56RI0eO148oplHX7hMWHwrFtB/P29YTU1/j+J9zzjkVrxN/gyO8Ouqoo8brKRavwaJ/VEztovVE+5GNNtqoyfc98VyNXroN/T2NkOnFF1+saJm2ThhFuxX9DuIXa8yDry160sQf0I8++qjVto1JF+HEkCFDcp+hspjzHv2iosfMDjvskJv0rbnmmvnND21XvLGNcSv3joqGmtEXKj5xD9FMN9R/LpdfFHsutx/R0y2et8cff3zNZVGJEeMfL6ijR0L0KIneJTfeeGOrbivNU8nz1HO5esQHBv/5z39y/6Do91buLxPP5bvvvjv1798/LbvssmneeefNFVe0XVHdFOMWFav77bdfDiSj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HyLFiWSivxSt45JLLsnTt+qLlhbxOqp80p+ojIkxbuiMiPG8jn6s8WFDBFGdOnXKH+r2799/gj3hmDwiMI4zlTYmgqU463R5yvRll12W3+9GABlnwowPeWurZJm2ShgFAAAAQGGUjgAAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEAAABQGGEUAAAAAIURRgEA0Cp++umn9PHHH6fRo0cbAQCYggijAAAo3I033pjmmmuu1K9fvzR48GAjAABTEGEUAACFe+ONN9Luu++e7r777hxKAQBTDmEUAACFe/7559PNN9+cNthgg3TdddcZAQCYgnQolUql1t4IAACKNXz48Pw199xzp44dO7bJw//ZZ5/l/3v27Jn//+6779KIESPSvPPOmzp06NDKWwcATCyVUQAAU6Bzzz03zT///Omjjz5qlfv/5ptv8n2PHDmy0WXWX3/9/FV2wgkn5G2OxucAQPsljAIAqBIR0kTAM3bs2PTll1+mr776KrVVd955Zw6WTj755NbeFACgYMIoAIAqcd9996U11lgjT2f761//mg4//PDUVm233XZp9tlnTxdddFH65ZdfWntzAIACCaMAAKrEpptumiujevToka655pp02WWXpbaqU6dOaa+99srT9a666qrW3hwAoEDCKACAKjVu3LhcJTVs2LBmr/fpp5+mb7/9Nk1O/fv3T507d07nnHNOck4dAJhyCKMAAKpE9Ig6/fTT07rrrpsWXnjhHPR07949HXzwwRXfxg8//JCWWGKJtMIKK6Qzzzxzsm5vVHDtsMMO6Z133kl33313i9/+hx9+WPGyY8aMyVVlX3zxRUXLR0VXLBvrAQDNI4wCAKgCgwYNSgsuuGA67LDD0n//+98cxHTr1q3ZtxMhS4RYN910U9p7773T5HbAAQfk///2t7+1+G3H2fd22mmnis6+F03fl1pqqdS3b99cGdaQqN4aOHBgmnfeeXOQNuecc6YZZpghrb766unqq69u8e0HgGoljAIAaOeiQmfbbbdNo0ePTkcddVR67bXX8vdDhgxp9m09++yzeWrf9ttvn/74xz+22DaOHDkyVx7VD4b69OmT/vCHP6SHHnoovfTSS6kl9ezZM1155ZW5yiuqrybUwyoqyqK6LI5BQ6Ih/D777JOPa5cuXXIYFcHVY489lnbfffcW3XYAqGbCKACAdu7xxx/PYc+OO+6YTjzxxDzNbqqpJu5l3tZbb51efvnl9PDDD+eQpSW3cf7550933nlnYdVRJ598crr00kvTxx9/nFZaaaX0xBNPNLn8Zpttlv9vaBsj8DvrrLPSzDPPnO65554cqn322Wd5WuP999+ftthiixbddgCoZsIoAIB2LvpChUcffTQHLm+++WY+Q9166603Ubd37rnn5uAoKpmaEgHN0KFDx7t8+PDhed2Y+laJqIxafPHF04033pgbp5eNGDEiTTPNNGlS7Lrrrunpp5/OIVJUPr366quNLrvBBhukaaedNt11113jXRcBXezP0UcfnW+ndkXV7373u3TttddO0nYCwJREGAUA0M6tssoqackll0zvvvtuWnXVVXOw8+c//7lmullM2auv3Bepof5Iv/zyS53/G7PNNtvkKqz6ooIowqzPP/+85rJRo0bl/xsLl/bff//066+/pvPPP78m/Im+V7169UqTKrYxKr2ih9af/vSnRs/cN+OMM6Y11lgjB1YffPBBnetmn332JrcfAKicMAoAoJ2Lap6YKta/f//chDu+4vsIVSJEaagX01tvvVXn/9pefPHF/H9jvZNqB0zff/99eu+99+pcXq6oiuvKyj2b5plnngZvK86qF03B//nPf+YQKhqPh8033zy1hAi19tprr3xMBg8e3Ohyv/nNb/L/11xzTZ3Ll1lmmdyo/NRTTx1vf8uN3x988MEW2VYAqHYdW3sDAACYdLPNNlu64IILxrs8pupdccUVufn2+uuvn2aaaab0yCOPpNtuuy1ff/DBB6fpp58+Vw1FZdCtt96ag60QzdAjzJpjjjnSrLPOWnObUVn0+uuvp1deeSX/vN122+WQJhqGx23HdLvy+tHDKqqMolqqa9euabHFFquzfTEtLyqiwkYbbZQuv/zy1Lt373xZVHlFY/bmiv5ZMYWwbMyYMblqLJqZRy+t2KcIyoYNG1azTFSPRVAV0xvD2WefnavN5ptvvjzFr9zTKqb9RTAV/bniWEaYF1Vc0Zcqfo4pigBA0zqUGqtTBgCg3fvkk0/y2eRqhzNlUYn09ddf10w/K4dC5altETg1dF3ZQgstlC+PIKa+CH3qTwGMhuJHHHHEeLfx/vvvj7f+2muvnUOtchBUnsr397//PTcNn2GGGRrd5wjTYv2GxG2cc8456aSTTsr9n+rr2LFjDqHK1WSdO3fO4daERJgX0yUb6jcFANSlMgoAoIrFtLjnn38+HXLIIen222/P1U9xWUyDizPnHXPMMXl62ZdffpkDlaiwGjBgQJ4ed9xxx6W77747936Kqp+yqKTq169fOuWUU/JUvdNPPz1XREXD8XnnnTcdeuihaeqpp04DBw7M0/Ni3ZiGF9Pk6pt77rlz5VKHDh1ywBT9rqLSKqqk4rLaZplllnz7EzpT4HTTTZeXqz2NccEFF8w9rqKiKcS+1l4mArc+ffrkCrKll146nXHGGemOO+5IQ4YMyZVhsS3xFeFUed1FFlkkB1ex/AILLDDe9gIADVMZBQAAAEBhNDAHAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAoDDCKAAAAAAKI4wCAAAAIBXl/wB6zJYfMMQZ5QAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1200x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "تم حفظ الرسم: saudi_labor_law_voice_agent_project\\05_reports\\figures\\04_ar_evaluation_dataset_composition.png\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Arabic Academic Visualisations - No Text Reversing Version\n",
    "# رسومات عربية بدون قلب النص\n",
    "# =========================================================\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "FIGURES_DIR.mkdir(parents=True, exist_ok=True)\n",
    "REPORTS_DIR.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "# مهم: لا نستخدم arabic_reshaper ولا bidi لأن بيئتك تقلب النص عند استخدامها\n",
    "def ar(text):\n",
    "    return str(text)\n",
    "\n",
    "matplotlib.rcParams[\"font.family\"] = [\"Tahoma\", \"Arial\", \"DejaVu Sans\"]\n",
    "matplotlib.rcParams[\"axes.unicode_minus\"] = False\n",
    "\n",
    "\n",
    "def save_current_fig(filename):\n",
    "    path = FIGURES_DIR / filename\n",
    "    plt.tight_layout()\n",
    "    plt.savefig(path, bbox_inches=\"tight\", dpi=300)\n",
    "    plt.show()\n",
    "    plt.close()\n",
    "    print(\"تم حفظ الرسم:\", path)\n",
    "\n",
    "\n",
    "def add_barh_labels(ax, values):\n",
    "    max_v = max(values) if len(values) else 1\n",
    "    for i, v in enumerate(values):\n",
    "        ax.text(\n",
    "            v + max_v * 0.01,\n",
    "            i,\n",
    "            str(int(v)),\n",
    "            va=\"center\",\n",
    "            fontsize=11\n",
    "        )\n",
    "\n",
    "\n",
    "# =========================================================\n",
    "# Figure 1 - اكتمال البيانات مقابل سلامة قاعدة الاسترجاع\n",
    "# =========================================================\n",
    "\n",
    "retention_df_ar = pd.DataFrame({\n",
    "    \"المرحلة\": [\n",
    "        \"السجلات القانونية الخام\",\n",
    "        \"السجلات القانونية بعد التنظيف\",\n",
    "        \"المواد الفعالة داخل قاعدة الاسترجاع\",\n",
    "        \"أرشيف المواد الملغاة\",\n",
    "        \"الأسئلة الشائعة الخام\",\n",
    "        \"الأسئلة الشائعة بعد التنظيف\",\n",
    "        \"أسئلة الفهرسة\",\n",
    "        \"أسئلة التقييم\",\n",
    "    ],\n",
    "    \"العدد\": [\n",
    "        len(df_articles_raw),\n",
    "        len(df_articles),\n",
    "        len(df_articles_active),\n",
    "        len(df_articles_repealed),\n",
    "        len(df_faq_raw),\n",
    "        len(df_faq),\n",
    "        len(df_faq_indexing),\n",
    "        len(df_faq_evaluation),\n",
    "    ]\n",
    "})\n",
    "\n",
    "display(retention_df_ar)\n",
    "\n",
    "plot_df = retention_df_ar.iloc[::-1].copy()\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(12, 6))\n",
    "labels = [ar(x) for x in plot_df[\"المرحلة\"]]\n",
    "values = plot_df[\"العدد\"].values\n",
    "\n",
    "ax.barh(labels, values)\n",
    "add_barh_labels(ax, values)\n",
    "\n",
    "ax.set_title(\"اكتمال البيانات مقابل سلامة قاعدة الاسترجاع\", fontsize=15)\n",
    "ax.set_xlabel(\"عدد السجلات\", fontsize=12)\n",
    "ax.grid(axis=\"x\", alpha=0.25)\n",
    "\n",
    "save_current_fig(\"01_ar_data_completeness_vs_retrieval_safety.png\")\n",
    "\n",
    "\n",
    "# =========================================================\n",
    "# Figure 2 - تقسيم الأسئلة الشائعة بدون تسريب\n",
    "# =========================================================\n",
    "\n",
    "faq_leakage_overlap = len(\n",
    "    set(df_faq_indexing[\"document_unit_id\"]) &\n",
    "    set(df_faq_evaluation[\"document_unit_id\"])\n",
    ")\n",
    "\n",
    "faq_split_df_ar = pd.DataFrame({\n",
    "    \"المجموعة\": [\n",
    "        \"أسئلة الفهرسة\",\n",
    "        \"أسئلة التقييم المعزولة\",\n",
    "        \"التسريب بين المجموعتين\",\n",
    "    ],\n",
    "    \"العدد\": [\n",
    "        len(df_faq_indexing),\n",
    "        len(df_faq_evaluation),\n",
    "        faq_leakage_overlap,\n",
    "    ]\n",
    "})\n",
    "\n",
    "display(faq_split_df_ar)\n",
    "\n",
    "plot_df = faq_split_df_ar.iloc[::-1].copy()\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(10, 4))\n",
    "labels = [ar(x) for x in plot_df[\"المجموعة\"]]\n",
    "values = plot_df[\"العدد\"].values\n",
    "\n",
    "ax.barh(labels, values)\n",
    "add_barh_labels(ax, values)\n",
    "\n",
    "ax.set_title(\"تقسيم الأسئلة الشائعة للتقييم بدون تسريب\", fontsize=15)\n",
    "ax.set_xlabel(\"عدد السجلات\", fontsize=12)\n",
    "ax.grid(axis=\"x\", alpha=0.25)\n",
    "\n",
    "save_current_fig(\"02_ar_faq_split_without_leakage.png\")\n",
    "\n",
    "\n",
    "# =========================================================\n",
    "# Figure 3 - مقارنة استراتيجيات التقسيم\n",
    "# =========================================================\n",
    "\n",
    "chunking_comparison_ar = pd.DataFrame({\n",
    "    \"الاستراتيجية\": [\n",
    "        \"التقسيم الهيكلي\",\n",
    "        \"التقسيم بالحجم الثابت\",\n",
    "    ],\n",
    "    \"عدد المقاطع\": [\n",
    "        len(df_structural_chunks),\n",
    "        len(df_fixed_chunks),\n",
    "    ]\n",
    "})\n",
    "\n",
    "display(chunking_comparison_ar)\n",
    "\n",
    "plot_df = chunking_comparison_ar.iloc[::-1].copy()\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(9, 4))\n",
    "labels = [ar(x) for x in plot_df[\"الاستراتيجية\"]]\n",
    "values = plot_df[\"عدد المقاطع\"].values\n",
    "\n",
    "ax.barh(labels, values)\n",
    "add_barh_labels(ax, values)\n",
    "\n",
    "ax.set_title(\"مقارنة عدد المقاطع حسب استراتيجية التقسيم\", fontsize=15)\n",
    "ax.set_xlabel(\"عدد المقاطع\", fontsize=12)\n",
    "ax.grid(axis=\"x\", alpha=0.25)\n",
    "\n",
    "save_current_fig(\"03_ar_chunking_strategy_comparison.png\")\n",
    "\n",
    "\n",
    "# =========================================================\n",
    "# Figure 4 - تركيب مجموعة التقييم\n",
    "# =========================================================\n",
    "\n",
    "eval_type_map = {\n",
    "    \"faq_retrieval\": \"تقييم الأسئلة الشائعة\",\n",
    "    \"legal_article_retrieval\": \"تقييم المواد القانونية\",\n",
    "    \"out_of_scope\": \"أسئلة خارج النطاق\",\n",
    "}\n",
    "\n",
    "eval_comp_ar = (\n",
    "    df_eval[\"eval_type\"]\n",
    "    .map(eval_type_map)\n",
    "    .fillna(df_eval[\"eval_type\"])\n",
    "    .value_counts()\n",
    "    .rename_axis(\"نوع التقييم\")\n",
    "    .reset_index(name=\"العدد\")\n",
    ")\n",
    "\n",
    "display(eval_comp_ar)\n",
    "\n",
    "plot_df = eval_comp_ar.iloc[::-1].copy()\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(10, 4))\n",
    "labels = [ar(x) for x in plot_df[\"نوع التقييم\"]]\n",
    "values = plot_df[\"العدد\"].values\n",
    "\n",
    "ax.barh(labels, values)\n",
    "add_barh_labels(ax, values)\n",
    "\n",
    "ax.set_title(\"تركيب مجموعة التقييم\", fontsize=15)\n",
    "ax.set_xlabel(\"عدد الأسئلة\", fontsize=12)\n",
    "ax.grid(axis=\"x\", alpha=0.25)\n",
    "\n",
    "save_current_fig(\"04_ar_evaluation_dataset_composition.png\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "d18b01b8-f9ca-4794-a8c7-bcdd74f4fb0d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>القطاع</th>\n",
       "      <th>عدد الأسئلة</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>قطاع العمل</td>\n",
       "      <td>271</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>قطاع الخدمة المدنية (العام)</td>\n",
       "      <td>226</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>قطاع التنمية الاجتماعية</td>\n",
       "      <td>105</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>غير محدد</td>\n",
       "      <td>87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>قطاع التنمية الاجتماعية | قطاع الخدمة المدنية (العام) | قطاع العمل</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>قطاع التنمية الاجتماعية | قطاع العمل</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                               القطاع  عدد الأسئلة\n",
       "0                                                          قطاع العمل          271\n",
       "1                                         قطاع الخدمة المدنية (العام)          226\n",
       "2                                             قطاع التنمية الاجتماعية          105\n",
       "3                                                            غير محدد           87\n",
       "4  قطاع التنمية الاجتماعية | قطاع الخدمة المدنية (العام) | قطاع العمل           10\n",
       "5                                قطاع التنمية الاجتماعية | قطاع العمل            4"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABKgAAAJLCAYAAADD3a4zAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAASdAAAEnQB3mYfeAAAgyFJREFUeJzt3QmcjfX////X2HeyJGQNZctSZCtpj5KkTxEhSklFWrVvlkqrFkuplLKlUCopiSgia4nsJPuWPed/e76//2t+Z8Y5M2dmzsw1c+Zxv93GmLNey5kz53per/frHRcIBAIGAAAAAAAA+CSHX08MAAAAAAAACAEVAAAAAAAAfEVABQAAAAAAAF8RUAEAAAAAAMBXBFQAAAAAAADwFQEVAAAAAAAAfEVABQAAAAAAAF8RUAEAAAAAAMBXBFQAAAAAAADwFQEVAAAAAAAAfEVABQAAAACIOV999ZVVrlzZ4uLirHfv3n4vDoBkxAUCgUByNwIAAAAAICupVq2aDRo0yNq1a+dCKgCZGxVUAAAAAICYU69ePZszZ47t3r3b70UBEAEqqAAAAAAAMWXZsmVWp06d+J9LlChhO3bs8HWZACSNgAoAAAAAAAC+YogfAAAAMoWuXbu6PjFvv/12yOtvv/12d/3QoUMzfNlmzpzpnrt58+YpWmZkfZlpH2em16EakIdalqyqWLFibn22bt2aKfc9kB0QUAEAAAAAYk6TJk2YwQ/IQgioAAAAAAAx584773TfR48ebQcOHPB7cQAkg4AKAAAAQKa1adMmVwVz1VVXuZ9r165t+fLli+pzHDx40K655hrLnz+/e67Dhw9bdpER29cv119/vZUqVcr27dtnH374od+LAyAZBFQAAADIdnRArino5YorrnA/M8NX9qUKG4VS6j8UCATSLaDRc+i11rhx43R5fCSUN29e6969u/v/W2+9xeYBMjkCKgAAAACZ1umnn+5Co6lTp7qfly1bFvUKp1q1atmaNWvsr7/+sv/++8+yk4zYvn7S5Ao5cuSwJUuW2OzZs/1enEyhd+/eLijV9tB+1/+ffPJJvxcLIKACAABA9L3//vvWtGlTK1y4sDv4CR5ClBnogPy3336Ln41MP5csWdLvxYJPnn32WVu9erWdc845litXLnvvvffS5XlUmaXX2rx58yw7eP75561EiRLu9/+TTz7xZRkqVqxorVu3dv9/8803fVkGAJHJFeHtAAAAgIh069Yt3Q7wkT2pwfX06dNdsLNu3Tpbu3atbd682fbu3WvvvPOO3XDDDWl6fIWU6U29nRSCqTpJ66EZ5tTEe+jQoRaL21fDJZ9++mlbvHixnXHGGeanXr162ZQpU2zixIm2bds2O/XUU9P9Offv32+vvvqqffnll26/axuXLVvWWrZsabfccovb/37Ray74dafQFMgMCKgAAAAQNToAVDiVJ08eGzRokP3vf/+zcuXKsYWRKhpuN2DAABsyZIgLS0Lh4Dpzbt9TTjnFBUE//fSTC2bUgN4vl19+uVWtWtUFRSNHjrT+/fun6/Mp5FNvu5UrVya4XENI9aVlGDx4sD3wwAOpevyHHnrI3X/atGnueYBYQQ8qAAAARI03jOf++++3vn37Zkg4NWHCBDv//PPdAbCG6bVv3971m0nK22+/bWeddZZrolytWjV76aWXCDpSUSGjoVsaEqcAokGDBnbbbbfZxx9/bNu3b7e0UjCiyp3HH3/chSc6ENcQrQULFrjnbtWqVdj77tq1y1544QW78MILrXTp0m4/67V42WWX2csvvxw2jElPwb2d1CRd6+dn9VRatm8kRo0a5Sqxbr75ZitQoIC1bdvW/KLXqXpRybBhw+zEiRPpPrRR4dTZZ5/t+jxp+x49etS2bNlir7/+urvNI4884qqqou3YsWMugNPrXiFh586d3e8DkBUQUAEAACBq/v77b/ddwUAox48ft927d0flufbs2eP6WmkqeR0E6uB/586drorrvPPOsy+++CJsv6E77rjDHUDqoFFVFf369XPDrZDQo48+6g7u9T2pKhzt90WLFtmIESOsY8eOLrC67rrr7Ouvv0518Kf9p33phR2qFtF+U58oHXxruUKZO3eu1alTx1Wn/PDDD25IlxcOaBjbvffe65qi//nnnycN89NjhnvtZoZtHU2p3b6RUiCkfe99ffbZZ5ae1OQ7qe2nYXUKsTds2BDfED695M6d233X+1OzZs2sSJEi7rIyZcrYTTfdZDlz5nTvhfoKJbnXoqpTtU1DVU8pEBw4cKB73es98sMPP7SLL77Yjhw5kqrnAjISARUAAACipmbNmu778uXLTwoNNHOUDtA+//zzND+PZlxr1KiRO8hWdcZrr73mgq8VK1a4gzaFVZ06dXIHaMFUGfLM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AAAAAADgKwIqAAAAAAAA+IqACgAAAAAAAL4ioAIAAAAAAICvCKgAAAAAAADgKwIqAAAAAAAA+IqACgAAAAAAAL4ioAIAAAAAAICvCKgAAAAAAADgKwIqAAAAAAAA+CqXv08PAAAAwC8ff/yxjR492r788suQ12/dutWGDh1qS5Yssfz589vll19uXbt2tRw5/t957vHjx9uwYcNC3r9Bgwb2/PPPp9vyAwBiBwEVAAAAkA3t27fPXnjhBVuxYkXI69etW2eNGze2bdu22dlnn227du2ycePG2bRp01wo5Vm/fr3NmDHDateubUWLFk3wGMeOHUv39QAAxAYCKgDI4r7//ntbs2aNde/e3TKbl156yS688EJ3Bj0zL2ckdECmg7ObbrrJ/RzN9Qn3WCNGjLDq1atbixYtkn2MCRMmWOnSpS1nzpzuoLJjx45pXi4AsWn37t12xRVX2PLly+3ff/+1vHnzhrzdww8/7MIpvf+pcioQCNjtt99uw4cPdxVXrVq1SnD7119/3b3nAwCQGvSgAoB0NHv2bHe2ee3atS6sSQ9ffPGFvfzyy+YHnXUfNGiQO3seyuOPP24//fRTipYzI7ZZakycONHeeuutdNnu4R5ryJAh7sAwEjrIPHTokB05csQOHDgQleUCEJty585tl156qfXp08eqVKkS8jZ6L5k8ebJdcMEFLpySuLg4e+qpp9z/x4wZk6HLDACIfVRQAUA6Onz4sAsONMRh7969Mbety5cvHz885IMPPojKY8b6NksvXbp0if9/y5YtfV0WAJlboUKF7Nlnn3X/X7BggW3evPmk2/zxxx928OBBVwEb7LTTTrOyZcu6+wEAEE0EVACQji655JL4/3tnnWNJ4cKFrV+/fvbYY49Z//797ayzzkrzY8baNtOQmOnTp9vvv//uKpy0fueee266PJcqsTS879prr3UHkACQWl5odcopp5x0nYYTr1y58qTLH3nkERd+qQ9VkyZN7LbbbrOCBQuyEwAAESGgAoB0poogfZDXMLgtW7a4ECclPTrUK+S7776zDRs2uIMCVceUKVMmKsummZXUq+iHH36wM844wzXDTam77rrLDcV78skn7ZNPPskU2ywSGq6noSu1atWK6vYIpkqwiy++2H7++ef4y/Lly5cuAdUDDzzgqtnk0UcfdeugpsYAkNr3LylQoMBJ1+l9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GJfigGrs2LF27NixZG8XFxdnhQsXthw5MqTNFQAAAAAAALJLQFWwYMH0WRIAAAAAAABkSxle3nTixAk7fvw4M/oBAAAAAADAn4Dqsccec72pHnrooYx+agAAAAAAAGSXgGrjxo22bt06Vy2VWKdOndz3Dz/8MD2eGgAAAAAAAFlMugRUt9xyi1WuXNmmT59+0nU1atSwUqVK2ZYtW1yIBQAAAAAAgOwtKgFV37597dxzz7XZs2e7n2+66Sb3/ZNPPgl5+7POOst9J6ACAAAAAABAVAKqVatW2a+//mp79uxxP7dr187y5ctnkyZNsiNHjpx0+zx58rjvR48eZQ8AAAAAAABkc1EJqAoWLOi+Hzp0yH0vUqSIXX311bZ371778ssvT7q9hveJhvoBAAAAAAAge4tKQOUN2Zs1a1b8ZRdccIH7PmrUqAS31bC+lStXWoECBaxWrVrReHoAAAAAAABkYbmi8SDdu3e3F1980d588007fvy4lSlTxoYMGWI5c+a0qVOn2sSJE+26666z//77zx588EE3u1/Xrl3jh/oBAAAAAAAg+4pKQFWhQgX7+OOP7bbbbrO3337bcuTIYffcc481btzYOnbsaO3bt7ezzz7bdu3aZZs2bbI6derYc889F42nBgAAAAAAQBYXlYBK2rRpY61atbI///zTihcvbqeddpq7vGzZsq6a6vfff3eVVT169LB7773XChcuHK2nBgAAAAAAQBaWK6oPliuX1axZM8FlzZs3d18AAAAAAABAujVJBwAAAAAAAFKLgAoAAAAAAACxM8QPAAAAyM40W/Unn3xic+bMsX379lnVqlWtW7dublIhT+/evd3EQeHo9tdcc00GLTEAAJkDFVQAAABAFOzdu9eaNGliXbt2tb///tvy5MljI0aMsOrVq9v48ePjb7d582Zbt27dSV+abOjzzz+3VatWsT8AANkOFVQAAABAFAwaNMh++eUXFzJphmsvtDr77LPtjjvusGuvvdZNKjRp0qSQ93/llVesb9++duaZZ7I/AADZDhVUAAAAQBQsXLjQfb/kkkviLytatKhdeOGFtnPnTvcVzr///msDBw60Bg0a2NVXX83+AABkOwRUAADECFVfbNmyxe/FALItDeWTd999N8Hlf/31l5UvX95OPfXUJH9/t23bZk8//XS6LycAAJkRQ/wAAIgR6mFz5MgRvxcDyLYeeeQR++abb+yuu+6y7777zvr06WN//PGH/fzzz25YX1xcXMj77d6921588UU777zzrHXr1hm+3AAAZAZUUAEAYppm0zp27Fiyt9PB5Kuvvmr//fefZTX79++3L774wvWtWbRoke3YscPvRQKypdNOO83efPNNy507t33//ffWokUL69mzp91///121VVXhb3fCy+8YHv27KF6CgCQrVFBBQCIaRs3brSWLVu6GbTKlCkT9nYbNmxw1Q6qYGjcuHH85Rqqc/ToUStZsqTVqVPHDeEJVwXhh6+//trNGLZ169b4yzRz2DPPPGMPPPBA2PtpKNH27dsTXLZ69ep0XVYg1un3UUHU888/b71797bJkyfbgAEDXG8pzeo3atSok+7zzz//2GuvvWbNmze3yy67zJflBgAgMyCgAgDENFUunHHGGe7gT0NsNJtWKBpWkyNHDjc8JzigUj+Y9evXx/+soEqzc3Xu3Nk1PpZly5ZZ7dq1EzzekiVLbP78+ValShV3u/QItTQ72A033OAqqK644gqrXLmyC6pmzpxps2bNSjKgUpXHU089FfVlArIzzcCnXlP6Ltddd521bdvWWrVqZe+9955169bNLrjgggT3ee6551yDdHpPAQCyOwIqAEDMa9eunZtJ68orr3TDbrxGxsFKlSpljRo1sunTp9vjjz8ef/ktt9ziKh+8GbgUAI0ePdpVVp177rku1DrllFPsq6++ir/PyJEj3bCeEydOuJ+bNm3qri9cuHCq10HBmQKp66+/Pv6yuXPnuss++ugj69ixY/zlhw4dstmzZyf5eL169UrwWF4FlQ6mAaTc4cOH7ffff7eLLrooweU5c+a0G2+80f0OL126NEFApcrN4cOHu/uo0hMAgOyMgAoAkC1cfPHFdu+997ogR5VNoSqaNLX7E0884UIfBVoSHFZ51PD4pptusgULFrifvWoJz8MPP2ylS5d2j6chhgqnHn30UdfjKjkff/yxHT9+3FVoBVMopgApOFQqUqSI+96sWbMEt82fP79deumlST6PZhNLakYxACmTL18+F1YvX77cTVaQN2/eBBMYiKqrgqmKUbelegoAAJqkAwCyEfWX+vXXX92sWqHUr1/fhUOh+sQcPHjQhUeqdNAQQE0b37BhQ1dx9dJLL8XfTperSbkOPIcNG2Zffvml3XbbbTZ1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AAAAXxFQAQAAAAAAwFcEVAAAAAAAAPAVARUAAAAAAAB8RUAFAAAAAAAAXxFQAQAAAAAAwFcEVAAAAAAAAPAVARUAAEhXzz33nHXt2tV2797NlgYAAEBIBFQAkAI7duyw2bNnWyAQYLsBERgyZIg9+uij9v7779u///7LNgMAAEBIBFRANrZr1y4Xthw/fjxdHn/16tW2dOnS+J/XrVtnixYtispjh3ushQsX2vr16yN6jBUrVtiGDRts48aNCZYzKd9++62df/75duTIEcssorldo23u3Ln2999/Z/rlzK6v5/T25Zdf2gMPPGClS5f2e1EAAACQyRFQAdnYrFmzXNiyZ8+edHn8QYMG2R133BH/89ChQ61z585Reexwj9WxY0d76623InoMVXR8/fXX9v3339vw4cMtPSgwWL58udvGCmvSQzS3a0pt3brVhZzhKmMuvfRSmzhxYoqWMyO2WWrwek4ZBWYdOnSwLl26WPv27dNprwAAACBW5PJ7AQDAL4MHD47//80335wuz6GKKx2oX3/99fbEE0/YN998Y7FElWQXXXSRPfjgg/bMM89E5TFjfZtl5ddzSqoz27RpY3Xq1LG3337b7r33Xl+XBwAAAJkfARWATGnv3r1uSNWhQ4esSpUqVrZs2XR5nm3btrkhaGeffbbFxcVF/fFvueWW+P/HYtBSsWJFt46vvvqq9enTx0qUKJHmx4zFbRYrr+dIHDt2zFVM6funn35qefLk8WU5AAAAkLUwxA9ApqLm46q2KFmypJ177rluCOK4cePS5bk+/vhjK1++vNWrV88aNmzoGqCnd1XJsmXLIu4pFOyff/6x+fPnu+Fv0TRnzhzbt2+f61m0adOmVD1G//79XSVVcAVPZthmyVmwYIFt37496tsju7yew7nrrrvsl19+scmTJ9upp57qyzIAAAAg6yGgApBq//33nxuK9euvv7ogIRree+89e/nlly1fvnzuILtZs2ZWrly5VD/eiRMn7I8//rDNmzefVGnSs2dPV91RvXp1tw7RHoakcGL06NHWokULtw4XXHCBNWrUyK1fpFatWuXuf9ppp7n7qmJJyztp0qSoLOMjjzziwh/17frhhx8ShDf6UvNubcOkVKhQwVU9vfHGGy5I83ubRUqBWuLG5OG2Ryy+nnUf9foK/lKVV1pMmzbNhg0bZs8++6wVLVrU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92N/rV692rp27ZrkUDHta1HIrwBk48aNbkht9+7drWXLlgluH8ltkH5GjBjhGqKHM2nSpPiJCvQZaNu2bS6Q0okdvRcHn8ThvTZjEFABAAAAAADAV/SgAgAAAAAAgK8IqAAAAAAAAOArAioAAAAAAAD4ioAKAAAAAAAAviKgAgAAAAAAgK8IqAAAAAAAAOArAioAAAAAAAD4ioAKAAAAAAAAviKgAgAAAIAQDh48aOvXr7cjR46wfQAgnRFQAQAAAEAiU6ZMsbJly1qLFi1s6dKlbB8ASGcEVAAAAACQyO+//26dOnWyqVOnWtWqVdk+AJDOCKgAAAAAIJH58+e7cOqqq66yd955h+0DAOksLhAIBNL7SQAAAAAgJfbt22e7du1yw+zy5MmTKTfe1q1b7b///rNy5cq5n/fs2eO+ypcvbzlz5vR78QAgS6GCCgAAAECmM3z4cKtcubKtWLHCl+dXOLZu3To7dOhQ2Nu0b9/e9ajyvPjii26Zt2/fnkFLCQCxg4AKAAAAQIbNiqfQ5/jx47Zt2zZXgZRZzZgxw4VN/fv393tRACBbIKACAAAAkCFmz55tF154oW3evNkeffRR69OnT6bd8u3atbOKFSu6/lMabggASF8EVAAAAAAyxGWXXeYqqBT8aAjfJ598kmm3vHpI3X333bZ//34bMWKE34sDADGPgAoAAACALzRf0+7du12/p5Teb8uWLene66lHjx5WuHBhe+2119ywRABA+iGgAgAAAJAhdu7caUOGDLFWrVpZ9erVLX/+/Fa8eHHr1atXxI9x+PBha9CggZ1zzjn29NNPp+vyFilSxLp3724bNmywCRMmRP3x165dG/FtNVugqs/+/vvviLe1bnvs2LE0LCEAZBwCKgAAAADp7quvvrKqVavafffdZ9OmTbM1a9a46qSU2rNnjwtrxo4da/fff7+lNw3z03C/l156KeqPrbDuhhtuiLjHVaNGjeyss85KMnQaOXKknXHGGVayZEkrW7asFSpUyJo2beouB4DMjIAKAAAAQLrSML7//e9/duDAARcqLV682I4ePeqG6Cn8SYn58+e7QOfmm2+2q666KmrLeOTIEVehpGUMppn82rZt6573xx9/tGgqV66cjRs3zlWDLV26NMnbajtpfbXuP/zwQ8jbPPvss3brrbe68E/VaWXKlHGXz507113OMEUAmRkBFQAAAIB09fPPP7tm4+3bt7fnn3/ezj77bMuRI3WHIldffbUtWbLEZs6caQsWLIjaMi5atMiFUaEat/ft29d9j3YV1cMPP2wffvihC+pU5fTtt98meftrr73WfZ8yZcpJ1+3du9cFVKpKmzRpkv3777+uT5e2u7ZVhw4dLC4uLqrLDwDRREAFAAAAIF2VKFEivpJH1T+///67jRkzxi6//HI3XC+lNAOgwqQVK1Ykebtt27bZxo0bQ4Y5qpaKtD9Ts2bN3PC6yZMn2+rVq+MvVzVT7ty5LS1uuukm++WXX1w1VZs2bVyYF86ll15qBQsWtKlTp550nSqwVAWmCjVVfHlhVJ48eaxFixZue6e0Wg0AMhIBFQAAAIB0pabmCnjWr19vF154odWsWdMFM7NmzXKVVBrul9iJEycSfA926NChBN/DueWWW1w/Js36F+ytt95yAddff/0Vf5nCHQkXOKmKSsvyyiuvuJ///PNPW758uVWoUMHSSg3jVeWkIXmdOnUKOxQvX758LtTTEL7EQwJLly6d5PIDQGZHQAUAAAAgXalyR43R1XC8Xr16VqdOHdcTyRtWp55UiUMkVVkFfw+2cOFC912VR0lR6KQqqd9++y3B5aqe8iqpPCtXrnTfy5cvH/KxNDxR17333nsu2FIPLAVW7dq1s2g47bTTrE+fPq5CK6l+VAr7ZPTo0Qkur1atmpsdUY3XFZwltmvXrmSHEAKAn3L5+uwAAAAAsoXixYvbq6++etLlV155pQ0dOtRVKF133XVWtGhRmzdvnn300Ufu+kceecQNEdTXKaec4vovaaidPPPMMy400lepUqUSPK4CJ2+4XNeuXV3vK1U7/fTTT/b++++7y5944gl3+ebNm+25555zFUrqjxVMfZy8Cq9rrrnGLWuNGjVc8KXm5t27d0/xtlBw9vfff8f/rGGOCr1GjBjhflYllYYPKlTy6PkUPHmz8b3xxhvu+RVMadvKwIEDrUePHtawYUNXiaVtooBPAd3atWtdUEijdACZVVwg8akKAAAAAMgg6hN17rnnhuwVpYBFDcS9oWvBPaNq165ty5YtC3mdR4GUejAF943yaGhh4uGDalo+YMCABJep4ksVXomdf/75NnHixATB2KOPPuqCLoVPqogKRwFckyZNQl6ngElBlYYSes3ZEy93/fr17ddff3U/a7a+5IY6SpEiRdx2njFjRrK3BQA/UEEFAAAAwDennnqqm43vgQcesAkTJliBAgXs9NNPdxVA3bp1s6eeesq++eYbF/qouqpkyZLWs2dP69y5s5u1TjPWqcpJ13n0GGpsrooiNQtXldR3331ne/bscY/dr18/V42lEEgVRoUKFbIbbrjB7rnnnpOWr2zZsu5+ogbl6p914403uhn1Es9EqMesWLFiss3I8+bN627nUYhWpUoVN1xQAZUXKAXfJleuXHbmmWe67aQZ/zSU79NPP3V9vdR/SuupLz12sWLFXDin3lYaTqmQrWrVqsziByBTo4IKAAAAAAAAvqJJOgAAAAAAAHxFQAUAAAAAAABfEVABAAAAAADAVwRUAAAAAAAA8BUBFQAAAAAAAHxFQAUAAAAAAABfEVABAAAAAADAVwRUAAAAAAAA8BUBFQAAAAAAAHxFQAUAAAAAAABfEVABAAAAAADAVwRUAAAAAAAA8BUBFQAAAAAAAHxFQAUAAAAAAABfEVABAAAAAADA/PT/Ac7cGWmGNeB9AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1200x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "تم حفظ الرسم: saudi_labor_law_voice_agent_project\\05_reports\\figures\\06_ar_faq_sectors_by_question_count.png\n",
      "التفسير: يوضح هذا الرسم تركّز الأسئلة الشائعة حسب القطاع، ويساعد في اكتشاف عدم توازن التصنيفات داخل بيانات FAQ.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Figure 6 - توزيع الأسئلة الشائعة حسب القطاع\n",
    "# بدون قلب النص العربي\n",
    "# =========================================================\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib\n",
    "\n",
    "# لا تستخدم arabic_reshaper ولا bidi في بيئتك الحالية\n",
    "matplotlib.rcParams[\"font.family\"] = [\"Tahoma\", \"Arial\", \"DejaVu Sans\"]\n",
    "matplotlib.rcParams[\"axes.unicode_minus\"] = False\n",
    "\n",
    "faq_sector_counts = (\n",
    "    df_faq[\"sector\"]\n",
    "    .replace(\"\", \"غير محدد\")\n",
    "    .fillna(\"غير محدد\")\n",
    "    .value_counts()\n",
    "    .head(12)\n",
    "    .rename_axis(\"القطاع\")\n",
    "    .reset_index(name=\"عدد الأسئلة\")\n",
    ")\n",
    "\n",
    "faq_sector_counts.to_csv(\n",
    "    REPORTS_DIR / \"visual_06_faq_sector_counts.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "display(faq_sector_counts)\n",
    "\n",
    "# نعكس الترتيب حتى يظهر الأعلى في أعلى الرسم\n",
    "plot_df = faq_sector_counts.iloc[::-1].copy()\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(10, 5))\n",
    "\n",
    "y_labels = plot_df[\"القطاع\"].astype(str).tolist()\n",
    "values = plot_df[\"عدد الأسئلة\"].values\n",
    "\n",
    "ax.barh(y_labels, values)\n",
    "\n",
    "# إضافة الأرقام بجانب الأعمدة\n",
    "max_v = max(values) if len(values) else 1\n",
    "for i, v in enumerate(values):\n",
    "    ax.text(\n",
    "        v + max_v * 0.01,\n",
    "        i,\n",
    "        str(int(v)),\n",
    "        va=\"center\",\n",
    "        fontsize=11\n",
    "    )\n",
    "\n",
    "ax.set_title(\"توزيع الأسئلة الشائعة حسب القطاع\", fontsize=15)\n",
    "ax.set_xlabel(\"عدد الأسئلة\", fontsize=12)\n",
    "ax.set_ylabel(\"القطاع\", fontsize=12)\n",
    "ax.grid(axis=\"x\", alpha=0.25)\n",
    "\n",
    "save_current_fig(\"06_ar_faq_sectors_by_question_count.png\")\n",
    "\n",
    "print(\"التفسير: يوضح هذا الرسم تركّز الأسئلة الشائعة حسب القطاع، ويساعد في اكتشاف عدم توازن التصنيفات داخل بيانات FAQ.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "678d3aa7",
   "metadata": {},
   "source": [
    "## Stage 15 — Final Output Files Manifest\n",
    "\n",
    "This stage verifies that all required output files from the data preparation notebook have been successfully generated.\n",
    "\n",
    "The manifest covers cleaned datasets, active and repealed legal article files, FAQ indexing and evaluation files, RAG knowledge-base files, chunk files, quality reports, and dataset summaries.\n",
    "\n",
    "This final check confirms that the notebook outputs are ready to be used in the next stage: embeddings, ChromaDB indexing, and retrieval evaluation.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "76b102ed",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Final data/report files:\n",
      "✅ saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_active_only_for_rag.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_repealed_archive_not_indexed.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\02_clean\\clean_hrsd_faq_classified.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_indexing_set.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_evaluation_set.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production_active_law_only.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\legal_article_rag_policy_split.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\data_quality_report.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\chunk_quality_report.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\chunk_length_summary.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.csv\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.xlsx\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.json\n",
      "\n",
      "Main academic figures:\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\figures\\01_ar_data_completeness_vs_retrieval_safety.png\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\figures\\02_ar_faq_split_without_leakage.png\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\figures\\03_ar_chunking_strategy_comparison.png\n",
      "✅ saudi_labor_law_voice_agent_project\\05_reports\\figures\\04_ar_evaluation_dataset_composition.png\n",
      "\n",
      "Summary:\n",
      "Total expected files: 25\n",
      "Existing files: 25\n",
      "Missing files: 0\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>file_group</th>\n",
       "      <th>file_name</th>\n",
       "      <th>file_path</th>\n",
       "      <th>exists</th>\n",
       "      <th>size_kb</th>\n",
       "      <th>status</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>clean_labor_law_articles.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>802.42</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>clean_labor_law_articles_active_only_for_rag.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_active_only_for_rag.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>767.77</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>clean_labor_law_articles_repealed_archive_not_indexed.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_repealed_archive_not_indexed.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>41.62</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>clean_hrsd_faq_classified.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\02_clean\\clean_hrsd_faq_classified.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2369.33</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>hrsd_faq_indexing_set.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_indexing_set.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>1737.71</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>hrsd_faq_evaluation_set.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_evaluation_set.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>635.76</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2186.34</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_knowledge_base_dataset_full_production_active_law_only.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production_active_law_only.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2764.25</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_knowledge_base_dataset_experiment_no_leakage.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2186.34</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_knowledge_base_dataset_full_production.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2764.25</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>legal_articles_repealed_archive_not_indexed.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>36.05</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_evaluation_dataset.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>255.91</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_chunks_structural_legal_experiment.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>1415.34</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>rag_chunks_fixed_size_experiment.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>1351.58</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>legal_article_rag_policy_split.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\legal_article_rag_policy_split.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>0.23</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>data_quality_report.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\data_quality_report.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>1.75</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>chunk_quality_report.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\chunk_quality_report.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>2.13</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>chunk_length_summary.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\chunk_length_summary.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>0.13</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>dataset_summary.csv</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.csv</td>\n",
       "      <td>True</td>\n",
       "      <td>3.04</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>dataset_summary.xlsx</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.xlsx</td>\n",
       "      <td>True</td>\n",
       "      <td>6.24</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>data_or_report</td>\n",
       "      <td>dataset_summary.json</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.json</td>\n",
       "      <td>True</td>\n",
       "      <td>5.12</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>main_academic_figure</td>\n",
       "      <td>01_ar_data_completeness_vs_retrieval_safety.png</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\figures\\01_ar_data_completeness_vs_retrieval_safety.png</td>\n",
       "      <td>True</td>\n",
       "      <td>128.44</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>main_academic_figure</td>\n",
       "      <td>02_ar_faq_split_without_leakage.png</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\figures\\02_ar_faq_split_without_leakage.png</td>\n",
       "      <td>True</td>\n",
       "      <td>62.69</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>main_academic_figure</td>\n",
       "      <td>03_ar_chunking_strategy_comparison.png</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\figures\\03_ar_chunking_strategy_comparison.png</td>\n",
       "      <td>True</td>\n",
       "      <td>56.42</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>main_academic_figure</td>\n",
       "      <td>04_ar_evaluation_dataset_composition.png</td>\n",
       "      <td>saudi_labor_law_voice_agent_project\\05_reports\\figures\\04_ar_evaluation_dataset_composition.png</td>\n",
       "      <td>True</td>\n",
       "      <td>63.12</td>\n",
       "      <td>OK</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              file_group                                                             file_name  \\\n",
       "0         data_or_report                                          clean_labor_law_articles.csv   \n",
       "1         data_or_report                      clean_labor_law_articles_active_only_for_rag.csv   \n",
       "2         data_or_report             clean_labor_law_articles_repealed_archive_not_indexed.csv   \n",
       "3         data_or_report                                         clean_hrsd_faq_classified.csv   \n",
       "4         data_or_report                                             hrsd_faq_indexing_set.csv   \n",
       "5         data_or_report                                           hrsd_faq_evaluation_set.csv   \n",
       "6         data_or_report  rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv   \n",
       "7         data_or_report        rag_knowledge_base_dataset_full_production_active_law_only.csv   \n",
       "8         data_or_report                  rag_knowledge_base_dataset_experiment_no_leakage.csv   \n",
       "9         data_or_report                        rag_knowledge_base_dataset_full_production.csv   \n",
       "10        data_or_report                       legal_articles_repealed_archive_not_indexed.csv   \n",
       "11        data_or_report                                            rag_evaluation_dataset.csv   \n",
       "12        data_or_report                            rag_chunks_structural_legal_experiment.csv   \n",
       "13        data_or_report                                  rag_chunks_fixed_size_experiment.csv   \n",
       "14        data_or_report                                    legal_article_rag_policy_split.csv   \n",
       "15        data_or_report                                               data_quality_report.csv   \n",
       "16        data_or_report                                              chunk_quality_report.csv   \n",
       "17        data_or_report                                              chunk_length_summary.csv   \n",
       "18        data_or_report                                                   dataset_summary.csv   \n",
       "19        data_or_report                                                  dataset_summary.xlsx   \n",
       "20        data_or_report                                                  dataset_summary.json   \n",
       "21  main_academic_figure                       01_ar_data_completeness_vs_retrieval_safety.png   \n",
       "22  main_academic_figure                                   02_ar_faq_split_without_leakage.png   \n",
       "23  main_academic_figure                                03_ar_chunking_strategy_comparison.png   \n",
       "24  main_academic_figure                              04_ar_evaluation_dataset_composition.png   \n",
       "\n",
       "                                                                                                            file_path  exists  size_kb status  \n",
       "0                                           saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles.csv    True   802.42     OK  \n",
       "1                       saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_active_only_for_rag.csv    True   767.77     OK  \n",
       "2              saudi_labor_law_voice_agent_project\\02_clean\\clean_labor_law_articles_repealed_archive_not_indexed.csv    True    41.62     OK  \n",
       "3                                          saudi_labor_law_voice_agent_project\\02_clean\\clean_hrsd_faq_classified.csv    True  2369.33     OK  \n",
       "4                                              saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_indexing_set.csv    True  1737.71     OK  \n",
       "5                                            saudi_labor_law_voice_agent_project\\03_final\\hrsd_faq_evaluation_set.csv    True   635.76     OK  \n",
       "6   saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv    True  2186.34     OK  \n",
       "7         saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production_active_law_only.csv    True  2764.25     OK  \n",
       "8                   saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage.csv    True  2186.34     OK  \n",
       "9                         saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_full_production.csv    True  2764.25     OK  \n",
       "10                       saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.csv    True    36.05     OK  \n",
       "11                                            saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv    True   255.91     OK  \n",
       "12                           saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.csv    True  1415.34     OK  \n",
       "13                                 saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.csv    True  1351.58     OK  \n",
       "14                                  saudi_labor_law_voice_agent_project\\05_reports\\legal_article_rag_policy_split.csv    True     0.23     OK  \n",
       "15                                             saudi_labor_law_voice_agent_project\\05_reports\\data_quality_report.csv    True     1.75     OK  \n",
       "16                                            saudi_labor_law_voice_agent_project\\05_reports\\chunk_quality_report.csv    True     2.13     OK  \n",
       "17                                            saudi_labor_law_voice_agent_project\\05_reports\\chunk_length_summary.csv    True     0.13     OK  \n",
       "18                                                 saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.csv    True     3.04     OK  \n",
       "19                                                saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.xlsx    True     6.24     OK  \n",
       "20                                                saudi_labor_law_voice_agent_project\\05_reports\\dataset_summary.json    True     5.12     OK  \n",
       "21             saudi_labor_law_voice_agent_project\\05_reports\\figures\\01_ar_data_completeness_vs_retrieval_safety.png    True   128.44     OK  \n",
       "22                         saudi_labor_law_voice_agent_project\\05_reports\\figures\\02_ar_faq_split_without_leakage.png    True    62.69     OK  \n",
       "23                      saudi_labor_law_voice_agent_project\\05_reports\\figures\\03_ar_chunking_strategy_comparison.png    True    56.42     OK  \n",
       "24                    saudi_labor_law_voice_agent_project\\05_reports\\figures\\04_ar_evaluation_dataset_composition.png    True    63.12     OK  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "All final output files were generated successfully.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 15 - Final Output Files Manifest\n",
    "# فحص نهائي لجميع مخرجات مرحلة إعداد البيانات\n",
    "# =========================================================\n",
    "\n",
    "from pathlib import Path\n",
    "import pandas as pd\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 1) Final required data/report files\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "output_files = [\n",
    "    # Cleaned datasets\n",
    "    CLEAN_DIR / \"clean_labor_law_articles.csv\",\n",
    "    CLEAN_DIR / \"clean_labor_law_articles_active_only_for_rag.csv\",\n",
    "    CLEAN_DIR / \"clean_labor_law_articles_repealed_archive_not_indexed.csv\",\n",
    "    CLEAN_DIR / \"clean_hrsd_faq_classified.csv\",\n",
    "\n",
    "    # Final split datasets\n",
    "    FINAL_DIR / \"hrsd_faq_indexing_set.csv\",\n",
    "    FINAL_DIR / \"hrsd_faq_evaluation_set.csv\",\n",
    "\n",
    "    # Final RAG knowledge bases\n",
    "    FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage_active_law_only.csv\",\n",
    "    FINAL_DIR / \"rag_knowledge_base_dataset_full_production_active_law_only.csv\",\n",
    "\n",
    "    # Legacy-compatible copies for next RAG notebook\n",
    "    FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage.csv\",\n",
    "    FINAL_DIR / \"rag_knowledge_base_dataset_full_production.csv\",\n",
    "\n",
    "    # Repealed archive\n",
    "    FINAL_DIR / \"legal_articles_repealed_archive_not_indexed.csv\",\n",
    "\n",
    "    # Evaluation dataset\n",
    "    FINAL_DIR / \"rag_evaluation_dataset.csv\",\n",
    "\n",
    "    # Chunks\n",
    "    CHUNKS_DIR / \"rag_chunks_structural_legal_experiment.csv\",\n",
    "    CHUNKS_DIR / \"rag_chunks_fixed_size_experiment.csv\",\n",
    "\n",
    "    # Reports\n",
    "    REPORTS_DIR / \"legal_article_rag_policy_split.csv\",\n",
    "    REPORTS_DIR / \"data_quality_report.csv\",\n",
    "    REPORTS_DIR / \"chunk_quality_report.csv\",\n",
    "    REPORTS_DIR / \"chunk_length_summary.csv\",\n",
    "    REPORTS_DIR / \"dataset_summary.csv\",\n",
    "    REPORTS_DIR / \"dataset_summary.xlsx\",\n",
    "    REPORTS_DIR / \"dataset_summary.json\",\n",
    "]\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 2) Main academic figures only\n",
    "# الأربع رسومات المعتمدة أكاديمياً\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "selected_figure_files = [\n",
    "    FIGURES_DIR / \"01_ar_data_completeness_vs_retrieval_safety.png\",\n",
    "    FIGURES_DIR / \"02_ar_faq_split_without_leakage.png\",\n",
    "    FIGURES_DIR / \"03_ar_chunking_strategy_comparison.png\",\n",
    "    FIGURES_DIR / \"04_ar_evaluation_dataset_composition.png\",\n",
    "]\n",
    "\n",
    "# لو كنت تستخدم النسخة الإنجليزية السابقة، أضفها كبديل إذا لم توجد العربية\n",
    "fallback_figure_files = [\n",
    "    FIGURES_DIR / \"01_data_completeness_vs_rag_safety_policy.png\",\n",
    "    FIGURES_DIR / \"05_faq_split_no_leakage.png\",\n",
    "    FIGURES_DIR / \"08_chunks_count_by_strategy.png\",\n",
    "    FIGURES_DIR / \"10_evaluation_dataset_composition.png\",\n",
    "]\n",
    "\n",
    "# اختيار الرسومات العربية إن وجدت، وإلا استخدام البديل الإنجليزي\n",
    "final_figure_files = []\n",
    "for ar_fig, en_fig in zip(selected_figure_files, fallback_figure_files):\n",
    "    if ar_fig.exists():\n",
    "        final_figure_files.append(ar_fig)\n",
    "    elif en_fig.exists():\n",
    "        final_figure_files.append(en_fig)\n",
    "    else:\n",
    "        final_figure_files.append(ar_fig)  # سيظهر Missing في التقرير\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 3) Build final manifest\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "manifest_rows = []\n",
    "\n",
    "def add_manifest_row(file_path, file_group):\n",
    "    file_path = Path(file_path)\n",
    "    manifest_rows.append({\n",
    "        \"file_group\": file_group,\n",
    "        \"file_name\": file_path.name,\n",
    "        \"file_path\": str(file_path),\n",
    "        \"exists\": file_path.exists(),\n",
    "        \"size_kb\": round(file_path.stat().st_size / 1024, 2) if file_path.exists() else 0,\n",
    "        \"status\": \"OK\" if file_path.exists() else \"MISSING\",\n",
    "    })\n",
    "\n",
    "for p in output_files:\n",
    "    add_manifest_row(p, \"data_or_report\")\n",
    "\n",
    "for p in final_figure_files:\n",
    "    add_manifest_row(p, \"main_academic_figure\")\n",
    "\n",
    "final_manifest = pd.DataFrame(manifest_rows)\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 4) Display final status\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "print(\"Final data/report files:\")\n",
    "for _, row in final_manifest[final_manifest[\"file_group\"] == \"data_or_report\"].iterrows():\n",
    "    icon = \"✅\" if row[\"exists\"] else \"❌\"\n",
    "    print(icon, row[\"file_path\"])\n",
    "\n",
    "print(\"\\nMain academic figures:\")\n",
    "for _, row in final_manifest[final_manifest[\"file_group\"] == \"main_academic_figure\"].iterrows():\n",
    "    icon = \"✅\" if row[\"exists\"] else \"❌\"\n",
    "    print(icon, row[\"file_path\"])\n",
    "\n",
    "print(\"\\nSummary:\")\n",
    "print(\"Total expected files:\", len(final_manifest))\n",
    "print(\"Existing files:\", int(final_manifest[\"exists\"].sum()))\n",
    "print(\"Missing files:\", int((~final_manifest[\"exists\"]).sum()))\n",
    "\n",
    "display(final_manifest)\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 5) Save final manifest\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "final_manifest.to_csv(\n",
    "    REPORTS_DIR / \"final_output_manifest.csv\",\n",
    "    index=False,\n",
    "    encoding=\"utf-8-sig\"\n",
    ")\n",
    "\n",
    "final_manifest.to_excel(\n",
    "    REPORTS_DIR / \"final_output_manifest.xlsx\",\n",
    "    index=False\n",
    ")\n",
    "\n",
    "# ---------------------------------------------------------\n",
    "# 6) Safety assertion\n",
    "# ---------------------------------------------------------\n",
    "\n",
    "missing_files = final_manifest[~final_manifest[\"exists\"]]\n",
    "\n",
    "if len(missing_files) > 0:\n",
    "    print(\"\\nMissing files found:\")\n",
    "    display(missing_files)\n",
    "else:\n",
    "    print(\"\\nAll final output files were generated successfully.\")\n",
    "\n",
    "assert missing_files.empty, \"Some final output files are missing. Please review the manifest above.\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9c2f200-ffe1-4228-b228-f4136794ff5f",
   "metadata": {},
   "source": [
    "### Interpretation — Final Output Manifest\n",
    "\n",
    "The output manifest provides a final reproducibility check for the data preparation stage.\n",
    "\n",
    "A successful result indicates that all core files required for the next notebook exist in the expected project directories. This reduces execution risk in later stages and makes the project easier to review, reproduce, and submit.\n",
    "\n",
    "The most important files for the next stage are the experimental no-leakage RAG knowledge base, the enriched evaluation dataset, and the structural and fixed-size chunk files.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2c2bddb",
   "metadata": {},
   "source": [
    "## Stage 16 — Readiness for the Retrieval Evaluation Stage\n",
    "\n",
    "This stage confirms that the data preparation outputs are ready for the next phase of the project.\n",
    "\n",
    "The next notebook will use the prepared knowledge base and chunk files to build embeddings, create or populate ChromaDB collections, and evaluate retrieval performance using metrics such as Recall@K, MRR, nDCG, article hit rate, and latency.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "e2a5702c-7d13-4331-a0a5-1f554899c433",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data preparation stage is complete.\n",
      "Next stage: embeddings, vector database, retrieval experiments, and evaluation metrics.\n",
      "\n",
      "Files required for the next stage:\n",
      "✅ Experimental RAG Knowledge Base => saudi_labor_law_voice_agent_project\\03_final\\rag_knowledge_base_dataset_experiment_no_leakage.csv\n",
      "✅ Evaluation Dataset => saudi_labor_law_voice_agent_project\\03_final\\rag_evaluation_dataset.csv\n",
      "✅ Structural Chunks => saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_structural_legal_experiment.csv\n",
      "✅ Fixed-size Chunks => saudi_labor_law_voice_agent_project\\04_chunks\\rag_chunks_fixed_size_experiment.csv\n",
      "✅ Repealed Legal Archive => saudi_labor_law_voice_agent_project\\03_final\\legal_articles_repealed_archive_not_indexed.csv\n",
      "\n",
      "Important notes:\n",
      "- Use the experimental KB for fair evaluation.\n",
      "- It contains active legal articles only.\n",
      "- FAQ evaluation records are held out and not indexed.\n",
      "- Repealed legal articles are archived but excluded from RAG indexing.\n",
      "\n",
      "Ready for the next stage.\n"
     ]
    }
   ],
   "source": [
    "# =========================================================\n",
    "# Stage 16 - Ready for Next Stage\n",
    "# جاهزية مخرجات إعداد البيانات للمرحلة التالية\n",
    "# =========================================================\n",
    "\n",
    "next_stage_files = {\n",
    "    \"Experimental RAG Knowledge Base\": FINAL_DIR / \"rag_knowledge_base_dataset_experiment_no_leakage.csv\",\n",
    "    \"Evaluation Dataset\": FINAL_DIR / \"rag_evaluation_dataset.csv\",\n",
    "    \"Structural Chunks\": CHUNKS_DIR / \"rag_chunks_structural_legal_experiment.csv\",\n",
    "    \"Fixed-size Chunks\": CHUNKS_DIR / \"rag_chunks_fixed_size_experiment.csv\",\n",
    "    \"Repealed Legal Archive\": FINAL_DIR / \"legal_articles_repealed_archive_not_indexed.csv\",\n",
    "}\n",
    "\n",
    "print(\"Data preparation stage is complete.\")\n",
    "print(\"Next stage: embeddings, vector database, retrieval experiments, and evaluation metrics.\")\n",
    "print(\"\\nFiles required for the next stage:\")\n",
    "\n",
    "missing_next_stage_files = []\n",
    "\n",
    "for name, path in next_stage_files.items():\n",
    "    status = \"✅\" if path.exists() else \"❌\"\n",
    "    print(status, name, \"=>\", path)\n",
    "    if not path.exists():\n",
    "        missing_next_stage_files.append((name, path))\n",
    "\n",
    "print(\"\\nImportant notes:\")\n",
    "print(\"- Use the experimental KB for fair evaluation.\")\n",
    "print(\"- It contains active legal articles only.\")\n",
    "print(\"- FAQ evaluation records are held out and not indexed.\")\n",
    "print(\"- Repealed legal articles are archived but excluded from RAG indexing.\")\n",
    "\n",
    "assert len(missing_next_stage_files) == 0, \"Some required files for the next stage are missing.\"\n",
    "\n",
    "print(\"\\nReady for the next stage.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "24e19a27-9ddf-450f-98c6-9b8554a7f37b",
   "metadata": {},
   "source": [
    "### Final Academic Summary — Stage 02\n",
    "\n",
    "This notebook completes the data preparation and knowledge base construction stage for the Arabic Saudi Labor Law RAG project.\n",
    "\n",
    "The stage produced a clean and auditable legal dataset, separated active and repealed legal provisions, prepared FAQ indexing and evaluation subsets, constructed safe experimental and production RAG knowledge bases, enriched the evaluation dataset with manual legal and out-of-scope questions, and generated two chunking strategies for later comparison.\n",
    "\n",
    "The key methodological contribution of this stage is the prevention of retrieval leakage and unsafe legal retrieval. Repealed legal articles are preserved for auditability but excluded from the retrieval corpus, while FAQ evaluation records are held out from the experimental knowledge base. These decisions support a fair and academically defensible retrieval evaluation in the next stage.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
