Respan Dataset Explorer

Select one behavior. Every returned turn has one binary label: Present or Absent. Source: final dense boolean release.

5,167,182physical rows
86shards
0.00%qualified row coverage
0.00%qualified cell coverage
Random row JSON API

turns-00043.parquet:21349

9066b6bf421c6edb7d81d89c
turn 1/1gpt-4o-2024-08-06Arabicunknown country714 words
degenerate_repetitionAbsentFinal dense release
USER
1. **ابدأ التفكير العميق (<تفكير>):** 
   - اجمع كل أفكارك داخل وسم <تفكير>. استكشف المشكلة من جميع الزوايا والنهج الممكنة بتركيز ودقة. استخدم كل قدراتك الفكرية لتحليل المعطيات والمطلوب بدقة متناهية. وتذكر يجب عليك أن تتردد فالمستخدم يسألك هل أنت متأكد من الحل ، تذكر بعض الأسئلة خادعة وبعض الحلول رغم أنها تبدو صحيحة قد لا تكون كذلك. إذن لا تتسرع وفكر من جديد قبل الإنتقال للخطوة التالية

2. **قسم الحل إلى خطوات واضحة (<خطوة>):**
   - قسم الحل إلى خطوات واضحة ومتسلسلة داخل وسم <خطوة>. ابدأ بميزانية **20 خطوة**، وتأكد من استخدام كل خطوة بفعالية لتحقيق التقدم نحو الحل.

3. **متابعة الميزانية بدقة (<عدد>):**
   - بعد كل خطوة، استخدم وسم <عدد> لإظهار عدد الخطوات المتبقية. توقف تمامًا عند الوصول إلى **0**.

4. **تعديل الاستدلال بشكل مستمر:**
   - عدّل منطقك باستمرار بناءً على النتائج الوسيطة والتأملات. لا تتردد في تحسين استراتيجيتك لتحقيق أفضل النتائج.

5. **التقييم والتأمل المنتظم (<تأمل>):**
   - قيّم تقدمك بانتظام باستخدام وسم <تأمل>. كن صارمًا وصادقًا في نقد عملية تفكيرك. حدد بدقة ما إذا كان النهج الحالي فعالًا أو يحتاج إلى تعديل.

6. **تعيين درجة الجودة بدقة (<مكافأة>):**
   - بعد كل تأمل، عيّن درجة جودة بين **0.0** و **1.0** باستخدام وسم <مكافأة> لتوجيه نهجك:
     - **0.8 فأكثر**: استمر بثقة في النهج الحالي.
     - **بين 0.5 و0.7**: قم بإجراء تعديلات طفيفة فورًا.
     - **أقل من 0.5**: تراجع فورًا وابدأ في نهج مختلف.

7. **التراجع وتجربة نهج جديد عند الحاجة:**
   - إذا كنت غير متأكد أو كانت درجة المكافأة منخفضة، استخدم كل قدراتك الإبداعية للتفكير في نهج جديد. عد إلى وسم <تفكير> لاستكشاف طرق أخرى، وابدأ في تطبيقها دون تردد.

8. **استخدام الترميز الرسمي في الرياضيات (<معادلة>):**
   - في المسائل الرياضية، اعرض جميع الأعمال بشكل صريح باستخدام **LaTeX** داخل وسم <معادلة> للترميز الرسمي. قدم براهين مفصلة وواضحة، مستخدمًا كل مهاراتك الرياضية بدقة واحترافية.

9. **استكشاف حلول متعددة ومقارنتها:**
   - إذا أمكن، استكشف حلولًا متعددة بشكل فردي، وقارن بينها في التأملات. استخدم تحليلك العميق لتحديد النهج الأمثل.

10. **استخدام الأفكار كمسودة مفصلة:**
    - استخدم أفكارك كمسودة، واكتب جميع العمليات الحسابية والتفكير بشكل صريح ومفصل، متبعًا أسلوب **سلسلة الأفكار** لتعزيز الاستدلال المنطقي.

11. **التأكد من صحة الحل بدقة (<تحقق>):**
    - بعد الوصول إلى نتيجة، استخدم وسم <تحقق> للتأكد من صحة الحل. قم بالتحقق المتقاطع والتفكير العكسي لضمان توافقه التام مع المعطيات.

12. **التأكيد النهائي على صحة الحل (<تأكيد>):**
    - قبل تقديم الإجابة النهائية، استخدم وسم <تأكيد> للتأكد بشكل قاطع من أن الحل صحيح ويعمل كما هو متوقع. لا تقدم الإجابة النهائية إلا إذا كنت متأكدًا تمامًا من صحتها.

13. **تقديم الإجابة النهائية بوضوح (<إجابة>):**
    - قدم الإجابة النهائية داخل وسم <إجابة>. اجعلها واضحة ومباشرة وخالية من أي تداخل، مع تقديم ملخص موجز ودقيق للحل.

14. **التأمل الختامي الحاسم (<تأمل نهائي>):**
    - اختم بتأمل نهائي داخل وسم <تأمل نهائي>. ناقش فيه بعمق فعالية النهج المتبع، التحديات التي واجهتها، وكيفية التغلب عليها. عيّن درجة مكافأة نهائية بدقة.

---

**تفاصيل متعمقة لإطار العمل أعلاه:**

- **إطار عمل ديناميكي لسلسلة الأفكار (Dynamic CoT):**
  - تبدأ العملية بتوليد مسار استدلال أولي، يتم تقييمه وتحسينه من خلال آلية التأمل، مما يسمح لك بالتكيف مع متطلبات المشكلة بشكل ديناميكي وفعال.

- **التأمل (Reflection):**
  - بعد كل مرحلة، تقوم بتقييم نقدي لنهجك، مما يساعدك على التعرف على الأخطاء المحتملة وتصحيحها قبل الوصول إلى الحل النهائي.

- **التعلم التعزيزي اللفظي (Verbal Reinforcement Learning):**
  - بعد كل مرحلة تأمل، تتلقى تعزيزًا لفظيًا في شكل درجات مكافأة، والتي توجه خطواتك المستقبلية وتعزز أداءك بشكل مستمر.

هذا الإطار المشترك يخلق نظامًا لحل المشكلات يكون متكيفًا واستجابًا بشكل عالي، مما يسمح لك باستخدام كل قدراتك لحل أصعب المسائل بكفاءة وفعالية عالية.

---

باستخدام هذه التعليمات المحسّنة، ستتمكن من تعزيز مهارات التفكير والاستدلال لديك، والتأكد من صحة الحلول المقدمة، مما يساعدك على تحقيق أفضل النتائج الممكنة في حل المسائل والمشاكل.

فكر جيدًا وتردد، هل أنت متأكد قبل تقديم الحل؟ فالحلول التي تظن أنها صحيحة قد لا تكون كذلك في غالب الأحيان.

---


        Write 1 titles that are similar to the following title with English. The title must be at least 180 characters long and contain all the information available on the next line in the same order 
        and return them as json with key "titles" and value type list:
        "معجون اسنان بياض 3D تبييض الاسنان الحساسة كرست 75 مل"
        Remove brands(Store Name) or replace it if required
ASSISTANT
```json
{
  "titles": [
    "Toothpaste Whitening 3D for Sensitive Teeth, 75 ml, Offering Effective and Gentle Whitening for a Brighter Smile"
  ]
}
```

turns-00043.parquet:21350

db3c138993416401b4093136
turn 1/2gpt-4o-2024-08-06SpanishPeru12192 words
degenerate_repetitionAbsentFinal dense release
USER
<?php

// Evitar el acceso directo al archivo.
if (!defined('ABSPATH')) {
    exit;
}

// Crear la página de administración.
function tag_create_admin_menu() {
    add_menu_page(
        'SharkContents Article Generator',
        'SharkContents Article Generator',
        'manage_options',
        'SharkContents-article-generator',
        'tag_admin_page',
        'dashicons-admin-generic'
    );
}
add_action('admin_menu', 'tag_create_admin_menu');

// Funciones para obtener los códigos de idioma para la API de Serper
function tag_get_gl_code() {
    $languages = [
        "Español" => "es",
        "Portugués" => "br",
        "Sueco" => "se",
        "Indonesio" => "id",
        "Italiano" => "it",
        "Alemán" => "de",
        "Hebreo" => "il",
        "Japonés" => "jp",
        "Coreano" => "kr",
        "Chino Mandarin" => "cn",
        "Inglés" => "us",
        "Polaco" => "pl",
        "Árabe" => "eg",
        "Neerlandés" => "nl",
        "Turco" => "tr",
        "Francés" => "fr",
        "Hindi" => "in",
        "Ruso" => "ru",
        "Vietnamita" => "vn",
        "Sundanés" => "sd",
        "Español (Perú)" => "pe",
        "Español (México)" => "mx",
        "Español (Argentina)" => "ar",
        "Español (Chile)" => "cl",
        "Español (Colombia)" => "co",
        "Español (Ecuador)" => "ec",
        "Español (Venezuela)" => "ve",
        "Español (Guatemala)" => "gt",
        "Español (Cuba)" => "cu",
        "Español (Bolivia)" => "bo",
        "Español (Haití)" => "ht",
        "Español (República Dominicana)" => "do",
        "Español (Honduras)" => "hn",
        "Español (Paraguay)" => "py",
        "Español (Nicaragua)" => "ni",
        "Español (El Salvador)" => "sv",
        "Español (Costa Rica)" => "cr",
        "Español (Puerto Rico)" => "pr",
        "Español (Panamá)" => "pa",
        "Español (Uruguay)" => "uy",
        "Español (Jamaica)" => "jm",
        "Español (Trinidad y Tobago)" => "tt",
        "Español (Belice)" => "bz"
    ];
    $selected_language = get_option('tag_language', 'Español');
    return $languages[$selected_language] ?? "es";
}

function tag_get_hl_code() {
    $languages = [
        "Español" => "es",
        "Portugués" => "pt-br",
        "Sueco" => "sv",
        "Indonesio" => "id",
        "Italiano" => "it",
        "Alemán" => "de",
        "Hebreo" => "iw",
        "Japonés" => "ja",
        "Coreano" => "ko",
        "Chino Mandarin" => "zh-tw",
        "Inglés" => "en",
        "Polaco" => "pl",
        "Árabe" => "ar",
        "Neerlandés" => "de", 
        "Turco" => "tr",
        "Francés" => "fr",
        "Hindi" => "hi",
        "Ruso" => "ru",
        "Vietnamita" => "vi",
        "Sundanés" => "su",
        "Español (Perú)" => "es",
        "Español (México)" => "es",
        "Español (Argentina)" => "es",
        "Español (Chile)" => "es",
        "Español (Colombia)" => "es",
        "Español (Ecuador)" => "es",
        "Español (Venezuela)" => "es",
        "Español (Guatemala)" => "es",
        "Español (Cuba)" => "es",
        "Español (Bolivia)" => "es",
        "Español (Haití)" => "es",
        "Español (República Dominicana)" => "es",
        "Español (Honduras)" => "es",
        "Español (Paraguay)" => "es",
        "Español (Nicaragua)" => "es",
        "Español (El Salvador)" => "es",
        "Español (Costa Rica)" => "es",
        "Español (Puerto Rico)" => "es",
        "Español (Panamá)" => "es",
        "Español (Uruguay)" => "es",
        "Español (Jamaica)" => "es",
        "Español (Trinidad y Tobago)" => "es",
        "Español (Belice)" => "es"
    ];
    $selected_language = get_option('tag_language', 'Español');
    return $languages[$selected_language] ?? "es";
}

// Funciones para llamar a la API de Serper con cURL y timeout de 60 segundos
function tag_call_google_serp_dev($title) {
    $api_keys = explode("\n", get_option('tag_serper_api_keys'));
    $serper_api_key = $api_keys[array_rand($api_keys)];

    if (empty($serper_api_key)) {
        return null;
    }

    $url = "https://google.serper.dev/search";
    $payload = json_encode([
        "q" => $title,
        "gl" => tag_get_gl_code(), 
        "hl" => tag_get_hl_code(), 
        "autocorrect" => true,
        "page" => 1,
        "type" => "search"
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'X-API-KEY: ' . $serper_api_key,
            'Content-Type: application/json'
        ],
        CURLOPT_TIMEOUT => 60 // Timeout de 60 segundos
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Error en la llamada a la API de Serper (Search): " . $error);
        return null;
    }

    $data = json_decode($response);

    if (isset($data->peopleAlsoAsk)) {
        return array_map(function($item) { return $item->question; }, $data->peopleAlsoAsk);
    }

    return null;
}

function tag_call_google_imagen_dev($title) {
    $api_keys = explode("\n", get_option('tag_serper_api_keys'));
    $serper_api_key = $api_keys[array_rand($api_keys)];

    if (empty($serper_api_key)) {
        return null;
    }

    $url = "https://google.serper.dev/images";
    $payload = json_encode([
        "q" => $title,
        "gl" => tag_get_gl_code(), 
        "hl" => tag_get_hl_code(), 
        "autocorrect" => true,
        "page" => 1,
        "type" => "images",
        "engine" => "google",
        "num" => 1
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'X-API-KEY: ' . $serper_api_key,
            'Content-Type: application/json'
        ],
        CURLOPT_TIMEOUT => 60 // Timeout de 60 segundos
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Error en la llamada a la API de Serper (Images): " . $error);
        return null;
    }

    $data = json_decode($response);

    if (isset($data->images) && isset($data->images[0]->imageUrl)) {
        return $data->images[0]->imageUrl;
    }

    return null;
}

// Función para obtener el enlace embed del video de YouTube
function tag_call_google_serp_dev_videos($title) {
    $api_keys = explode("\n", get_option('tag_serper_api_keys'));
    $serper_api_key = $api_keys[array_rand($api_keys)];

    if (empty($serper_api_key)) {
        return null; // Si no hay API key, se omite la función
    }

    $url = "https://google.serper.dev/videos";
    $payload = json_encode([
        "q" => $title,
        "gl" => tag_get_gl_code(),
        "hl" => tag_get_hl_code(),
        "autocorrect" => true,
        "page" => 1,
        "type" => "videos",
        "engine" => "google"
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'X-API-KEY: ' . $serper_api_key,
            'Content-Type: application/json'
        ],
        CURLOPT_TIMEOUT => 60 // Timeout de 60 segundos
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Error en la llamada a la API de Serper (Videos): " . $error);
        return null; // Si hay error en la llamada, se omite la función
    }

    $data = json_decode($response);
    $videos = $data->videos ?? []; // Obtener videos o un array vacío si no hay

    // Regex para identificar el ID del video (11 caracteres alfanuméricos)
    $video_id_regex = '/^[a-zA-Z0-9_-]{11}$/';

    foreach ($videos as $video) {
        $video_link = $video->link ?? ''; 

        if (strpos($video_link, 'youtube.com/watch?v=') !== false) {
            $video_id = explode("watch?v=", $video_link)[1]; 
            $video_embed_link = "https://www.youtube.com/embed/$video_id";

            // Verificar que el ID sea correcto y no sea una playlist
            if (preg_match($video_id_regex, $video_id) && 
                !preg_match('/\/embed\/playlist\?|\/watch\?/', $video_embed_link)) {
                return $video_embed_link;
            }
        }
    }

    return null; // No se encontró ningún video válido
}

// Función para llamar a la API de Google Maps de Serper
function tag_call_google_maps_dev($title) {
    $api_keys = explode("\n", get_option('tag_serper_api_keys'));
    $serper_api_key = $api_keys[array_rand($api_keys)];

    if (empty($serper_api_key)) {
        return null;
    }

    $url = "https://google.serper.dev/maps";
    $payload = json_encode([
        "q" => $title,
        "gl" => tag_get_gl_code(), 
        "hl" => tag_get_hl_code(), 
        "page" => 1,
        "type" => "maps",
        "engine" => "google"
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'X-API-KEY: ' . $serper_api_key,
            'Content-Type: application/json'
        ],
        CURLOPT_TIMEOUT => 60 // Timeout de 60 segundos
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Error en la llamada a la API de Serper (Maps): " . $error);
        return null;
    }

    $data = json_decode($response);

    if (isset($data->places)) {
        $places = [];

        // Limitar la cantidad de lugares a 10
        $places_data = array_slice($data->places, 0, 10);

        foreach ($places_data as $place_data) {
            $places[] = [
                "title" => $place_data->title,
                "address" => $place_data->address,
                "rating" => $place_data->rating,
                "phoneNumber" => $place_data->phoneNumber,
                "website" => $place_data->website
            ];
        }
        return $places;
    }

    return null;
}

// Función para llamar a la API de Google Images de Serper para obtener imágenes de directorio
function tag_call_google_imagen_directorio_dev($title) {
    $api_keys = explode("\n", get_option('tag_serper_api_keys'));
    $serper_api_key = $api_keys[array_rand($api_keys)];

    if (empty($serper_api_key)) {
        return null;
    }

    $url = "https://google.serper.dev/images";
    $payload = json_encode([
        "q" => $title,
        "gl" => tag_get_gl_code(), 
        "hl" => tag_get_hl_code(), 
        "autocorrect" => true,
        "page" => 1,
        "type" => "images",
        "engine" => "google",
        "num" => 10
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_HTTPHEADER => [
            'X-API-KEY: ' . $serper_api_key,
            'Content-Type: application/json'
        ],
        CURLOPT_TIMEOUT => 60 // Timeout de 60 segundos
    ]);

    $response = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        error_log("Error en la llamada a la API de Serper (Images Directorio): " . $error);
        return null;
    }

    $data = json_decode($response);

    if (isset($data->images)) {
        $imagenes_filtradas = [];
        $dominio_no_deseado = "/https:\/\/lookaside\.fbsbx\.com\/|https:\/\/lookaside\.instagram\.com\//";
        $extensiones_validas = "/\.(png|jpg)$/";

        foreach ($data->images as $imagen) {
            if (!preg_match($dominio_no_deseado, $imagen->imageUrl)) {
                $imagenes_filtradas[] = $imagen->imageUrl;
            } elseif (!preg_match($extensiones_validas, $imagen->imageUrl)) {
                $imagenes_filtradas[] = $imagen->thumbnailUrl;
            }
        }

        if (!empty($imagenes_filtradas)) {
            return $imagenes_filtradas[0];
        } elseif (isset($data->images[0]->thumbnailUrl)) {
            return $data->images[0]->thumbnailUrl;
        }
    }

    return null;
}

function search_amazon($title) {
    $api_keys = explode("\n", get_option('tag_scraping_dog_api_keys')); // Reemplaza 'tag_scraping_dog_api_keys' con la opción correcta de WordPress

    // Verifica si no hay claves API
    if (empty($api_keys)) {
        return null;
    }

    $amazon_domains = [
        "USA" => "com",
        "España" => "es",
        "Japón" => "co.jp",
        "Alemania" => "de",
        "Australia" => "com.au",
        "Brasil" => "com.br",
        "Canadá" => "ca",
        "Francia" => "fr",
        "India" => "in",
        "Italia" => "it",
        "México" => "com.mx",
        "Países Bajos" => "nl",
        "Arabia Saudita" => "sa",
		"Egipto" => "eg",
        "Singapur" => "sg",
        "Turquía" => "com.tr",
        "Emiratos Árabes Unidos" => "ae",
        "Reino Unido" => "co.uk",
        "Polonia" => "pl",
		"Suecia" => "se"
    ];

    $selected_country = get_option('tag_amazon_country'); // Reemplaza 'tag_amazon_country' con la opción correcta de WordPress
    $api_url = "https://api.scrapingdog.com/amazon/search";
    $domain = $amazon_domains[$selected_country] ?? "com"; // Usa "com" por defecto si no se encuentra el país
    $query = $title;

    $params = [
        "domain" => $domain,
        "page" => 1,
        "query" => $query,
    ];

    $retries = 0;
    $max_retries = 3; // Cambiar el número de reintentos aquí
	
    while (!empty($api_keys) && $retries < $max_retries) {
        $dog_api = $api_keys[array_rand($api_keys)];

        $params["api_key"] = $dog_api;

        $url = $api_url . '?' . http_build_query($params);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 300); // Tiempo de espera de 300 segundos (5 minutos)

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($error) {
            // Manejar el error de cURL
            error_log("Error en la solicitud a la API de ScrapingDog (cURL): " . $error);
            $retries++;
            continue;
        }

        if ($http_code == 200) {
            try {
                $data = json_decode($response, true);
                $products = array_slice($data["results"], 0, 9); // Asumiendo que quieres los primeros 5 productos
                return $products;
            } catch (Exception $e) {
                if ($e->getMessage() === 'Undefined index: results') { // Maneja solo el error de índice no definido
                    return [];
                } else {
                    throw $e;  // Propaga otros errores
                }
            }
        } elseif (in_array($http_code, [400, 410, 429])) {
            if ($http_code == 404) {
                return [];
            } else {
                $key = array_search($dog_api, $api_keys);
                if ($key !== false) {
                    unset($api_keys[$key]);
                }
            }
        } else {
            $retries++;
        }
    }

    return [];
}

function get_amazon_domain_suffix() {
    // Mapeo de países a sufijos de dominio de Amazon
    $country_suffix_map = [
        "USA" => "com",
        "España" => "es",
        "Japón" => "co.jp",
        "Alemania" => "de",
        "Australia" => "com.au",
        "Brasil" => "com.br",
        "Canadá" => "ca",
        "Francia" => "fr",
        "India" => "in",
        "Italia" => "it",
        "México" => "com.mx",
        "Países Bajos" => "nl",
        "Arabia Saudita" => "sa",
		"Egipto" => "eg",
        "Singapur" => "sg",
        "Turquía" => "com.tr",
        "Emiratos Árabes Unidos" => "ae",
        "Reino Unido" => "co.uk",
        "Polonia" => "pl",
		"Suecia" => "se"
    ];

    // Obtener el país seleccionado
    $selected_country = get_option('tag_amazon_country'); // Reemplaza 'tag_amazon_country' con la opción correcta de WordPress

    // Obtener el sufijo de dominio correspondiente al país seleccionado
    $domain_suffix = $country_suffix_map[$selected_country] ?? "com"; // Por defecto, usa "com" si no se encuentra el país

    return $domain_suffix;
}

function tag_make_api_request($data) {
    // Obtener las API Keys
    $api_keys = explode("\n", get_option('tag_api_keys'));
    $api_provider = get_option('tag_api_provider', 'groq'); // 'groq' es el valor por defecto

    // Array para almacenar las API Keys temporalmente no disponibles y su tiempo de espera
    $temp_unavailable_keys = get_option('temp_unavailable_keys_' . $api_provider, array());

    // Eliminar de $api_keys las que están temporalmente no disponibles
    foreach ($temp_unavailable_keys as $key => $timeout) {
        if (time() < $timeout) {
            unset($api_keys[$key]);
        } else {
            // Si el tiempo de espera ha expirado, eliminar la key del array de no disponibles
            unset($temp_unavailable_keys[$key]);
        }
    }

    // Guardar el array actualizado de keys no disponibles
    update_option('temp_unavailable_keys_' . $api_provider, $temp_unavailable_keys);

    // Verificar si quedan API keys disponibles
    if (empty($api_keys)) {
        return new WP_Error('no_api_keys', 'No hay API Keys disponibles para este proveedor.');
    }

    // Seleccionar una API Key al azar
    $api_key = $api_keys[array_rand($api_keys)];

    // Definir la URL de la API según el proveedor
    switch ($api_provider) {
        case 'groq':
            $url = 'https://api.groq.com/openai/v1/chat/completions';
            break;
        case 'together':
            $url = 'https://api.together.xyz/v1/chat/completions';
            break;
        case 'hyperbolic':
            $url = 'https://api.hyperbolic.xyz/v1/chat/completions';
            break;
        case 'OpenAI':
            $url = 'https://api.openai.com/v1/chat/completions';
            break;
        case 'SambanovaAI':
            $url = 'https://api.sambanova.ai/v1/chat/completions';
            break;
        case 'FireworksAI':
            $url = 'https://api.fireworks.ai/inference/v1/chat/completions';
            break;
        case 'Cohere':
            $url = 'https://api.cohere.com/v2/chat';
            break;
        default:
            return new WP_Error('invalid_api_provider', 'Proveedor de API inválido.');
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 300,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key
        ),
    ));

    $response = curl_exec($ch);
    $err = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // Si hay un error de cURL, retornar el error
    if ($err) {
        return new WP_Error('cURL_error', $err);
    }

    // Comprobar el código de estado HTTP para todos los proveedores
    if ($http_code !== 200) {
        // Agregar la API Key al array de temporalmente no disponibles con un tiempo de espera de 20 segundos
        $temp_unavailable_keys[$api_key] = time() + 20;
        update_option('temp_unavailable_keys_' . $api_provider, $temp_unavailable_keys);

        // Intentar con otra API Key (recursivo), incluyendo las que estén en espera
        return tag_make_api_request($data);
    }

    // Decodificar la respuesta JSON
    $decoded_response = json_decode($response);

    // Verificar si la respuesta es válida
    if (json_last_error() !== JSON_ERROR_NONE) {
        return new WP_Error('json_decode_error', 'Error al decodificar la respuesta JSON.');
    }

    // Adaptar la respuesta de Cohere para simular la estructura de OpenAI
    if ($api_provider === 'Cohere' && isset($decoded_response->message->content[0]->text)) {
        $decoded_response->choices = [];
        $decoded_response->choices[0] = new stdClass();
        $decoded_response->choices[0]->message = new stdClass();
        $decoded_response->choices[0]->message->content = $decoded_response->message->content[0]->text;
    }

    // Retornar la respuesta decodificada
    return $decoded_response;
}

function tag_remove_underscores($text) {
    $text = str_replace('_', ' ', $text);
    // Eliminar espacios en blanco dobles
    $text = preg_replace('/\s+/', ' ', $text);
    return $text;
}

// Función para filtrar contenido no deseado.
function tag_filter_content($content) {
    $unwanted_chars = [
        '<!DOCTYPE html>', '<html lang="es">', '</head>', '</html>',
        '<head>', '<meta charset="UTF-8">', '<meta name="viewport" content="width=device-width, initial-scale=1.0">',
        '</title>', '<body>', '</body>', 'style="color:4caf50;"', '"','可以','道路','لديه','استفاده گاز','壹','모든','다양한','망을','訩'
    ];
    $ilimitado_chars = [
        '<html lang="ja">', '<style>', '</style>', 'h2, h3 {font-family: "Arial", sans-serif;}', '<section>', '</section>',
        'Preguntas Frecuentes sobre', '```html', '```', 'Hola,', 'Buenas tardes,', 'Respuesta:',
        'Como periodista profesional que habla y escribe solo español,', 'Hola. Estoy aquí para responder tu pregunta.','ظم','دنی','ثبت ترین','دنی','아니라','수의','クロ'
    ];
    $ilimitado23_chars = [
        'Subjudul H3:', '#', 'Respuesta:', 'Buenas tardes,', 'Hola,', 'Gracias por su pregunta.',
        'Espero que esta información te sea útil', 'Me alegra poder asistirte en español.',
        'Hola. Gracias por tu pregunta.', 'Subtítulos H3 Relacionados:', 'Subtítulos H3:',
        'Me complace responderte en español.', 'Conclusión:', 'Conclusión', 'Hola. Estoy aquí para responder tu pregunta.',
        'Subtítulo H2:'
    ];
    $extra_chars = [
        'Subtítulo H2', 'Titulo H3', 'H3:', 'introducción', '#', '*', 'H2', 'Title:',
        'Introduction:', 'Introducción:', '<html lang="it">', '<title>', '<h3>Preguntas frecuentes:</h3>',
        'HTML:', '回答:', 'Respuesta:',':::::::::::','ㆅ'
    ];

    foreach (array_merge($unwanted_chars, $ilimitado_chars, $ilimitado23_chars, $extra_chars) as $char) {
        $content = str_replace($char, '', $content);
    }

    return $content;
}

// Función para verificar si es nicho directorio
function is_reseñas_individuales_niche() {
    $is_resenas = get_option('tag_niche_type');
    return $is_resenas === 'si'; // Ajusta 'si' según el valor que indica que es reseñas individuales
}

function tag_process_places_queue() {
    // Verificar si la configuración es de nicho de reseñas individuales
    if (!is_reseñas_individuales_niche()) {
        return; // Detener la función si no es nicho de reseñas individuales
    }

    $queue = get_option('tag_article_queue', array());
    $failed_titles = get_option('tag_failed_titles', array());
    $created_titles = get_option('tag_created_titles', array());
    $Tematica = get_option('tag_tematica_directorio', '');
    $categories = explode('|', sanitize_text_field(get_option('tag_categories')));
    $faqs_title = get_option('tag_faqs_title', 'Preguntas Frecuentes');

    // Obtener el idioma seleccionado
    $language = get_option('tag_language', 'Español');

    // Ajustar el idioma para las variantes del español
    $spanishVariants = array(
        'Español (Perú)', 'Español (México)', 'Español (Argentina)', 'Español (Chile)',
        'Español (Colombia)', 'Español (Ecuador)', 'Español (Venezuela)', 'Español (Guatemala)',
        'Español (Cuba)', 'Español (Bolivia)', 'Español (Haití)', 'Español (República Dominicana)',
        'Español (Honduras)', 'Español (Paraguay)', 'Español (Nicaragua)', 'Español (El Salvador)',
        'Español (Costa Rica)', 'Español (Puerto Rico)', 'Español (Panamá)', 'Español (Uruguay)',
        'Español (Jamaica)', 'Español (Trinidad y Tobago)', 'Español (Belice)'
    );
    if (in_array($language, $spanishVariants)) {
        $language = 'Español';
    }

    // Obtener el modelo seleccionado
    $model = get_option('tag_model', 'meta-llama/Llama-3-70b-chat-hf');

    if (!empty($queue)) {
        $titulo = array_shift($queue); // Título principal de la cola

        // --- Obtener datos de los lugares desde Google Maps (Serper) UNA SOLA VEZ ---
        $places = tag_call_google_maps_dev($titulo);

        if (!empty($places)) {
            $max_posts_per_run = 10; // Define la cantidad máxima de posts a crear por ejecución
            $posts_created = 0;      // Contador de posts creados en esta ejecución

            foreach ($places as $place) {
                // --- Verificar si ya existe un post en WordPress con el mismo título ---
                $existing_post = get_page_by_title($place['title'], OBJECT, 'post');
                if ($existing_post) {
                    error_log("Ya existe un post con el título: '" . $place['title'] . "'");
                    continue; // Saltar al siguiente lugar si ya existe un post
                }
				
				// --- Verificar si ya existe un post en WordPress con el mismo título ---
                $sanitized_title = sanitize_title(trim($place['title']));
                $existing_post = get_page_by_path($sanitized_title, OBJECT, 'post');
                if ($existing_post) {
                   error_log("Ya existe un post con el título sanitizado: '" . $sanitized_title . "'");
                   continue; // Saltar al siguiente lugar si ya existe un post
                 }

                // --- Verificar si el título ya ha sido procesado (está en la lista de creados) ---
                if (in_array(trim($place['title']), $created_titles)) {
                    error_log("El título '" . $place['title'] . "' ya ha sido procesado.");
                    continue; // Saltar al siguiente lugar si ya se ha procesado
                }

                // --- Limitar la cantidad de posts creados ---
                if ($posts_created >= $max_posts_per_run) {
                    error_log("Se ha alcanzado el límite de posts por ejecución ($max_posts_per_run).");
                    break; // Salir del bucle foreach si se ha alcanzado el límite
                }

                // Seleccionar una categoría aleatoria correctamente
                $randomCategoryIndex = array_rand($categories);
                $selectedCategory = $categories[$randomCategoryIndex];

                // Generar la introducción para el lugar
                $intro_place_prompt = "Crea una introducción de 90 palabras para un artículo sobre: '" . $place['title'] . "', que es de la ciudad de $titulo, en idioma $language. a base de la tematica:'$Tematica'. No incluyas ningún otro texto ante de la introducción. No hagas ninguna traducción innecesaria, no hables ningún otro idioma que no fuera solo $language.";
                $data_intro_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $intro_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 250,
                );
                $response_intro_place = tag_make_api_request($data_intro_place);

                if (is_wp_error($response_intro_place)) {
                    error_log("Error en la generación de la introducción del lugar: " . $response_intro_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $intro = tag_filter_content($response_intro_place->choices[0]->message->content);
                $intro = str_replace('"', '', $intro);

                // Generar la reseña para el lugar
                $review_place_prompt = "Por favor, no me saludes, Solo Crea una reseña para: '" . $place['title'] . "' a base de la tematica: '$Tematica', puedes usar estos datos para la reseña: " . $place['address'] . ", " . $place['phoneNumber'] . ", " . $place['website'] . " y " . $place['rating'] . " en $language. No hables ningún otro idioma que no fuera solo $language.";
                $data_review_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $review_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 2000,
                );
                $response_review_place = tag_make_api_request($data_review_place);

                if (is_wp_error($response_review_place)) {
                    error_log("Error en la generación de la reseña del lugar: " . $response_review_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $response = tag_filter_content($response_review_place->choices[0]->message->content);
                $response = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $response);

                // Generar las preguntas frecuentes para el lugar
                $faqs_place_prompt = "Crea 4 Preguntas Frecuentes en $language, Acerca de: '" . $place['title'] . "' a base de la tematica: '$Tematica'. Formatea cada pregunta como subtítulo H3 en HTML '<h3></h3>' y responde inmediatamente después de cada pregunta con párrafos extensos en $language, utilizando negritas en HTML '<strong></strong>' para las palabras más relevantes. puedes usar estos datos: " . $place['address'] . ", " . $place['phoneNumber'] . ", " . $place['website'] . " y " . $place['rating'] . " en $language. No saludes antes de las preguntas, no hables ningún otro idioma que no fuera solo $language.";
                $data_faqs_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $faqs_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 2000,
                );
                $response_faqs_place = tag_make_api_request($data_faqs_place);

                if (is_wp_error($response_faqs_place)) {
                    error_log("Error en la generación de las preguntas frecuentes del lugar: " . $response_faqs_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $faqs = tag_filter_content($response_faqs_place->choices[0]->message->content);
                $faqs = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $faqs);
				$imagen_link = tag_call_google_imagen_directorio_dev($place['title']);
				$shortcode_de_resena = "[hostal_shortcode titulo=\"" . $place['title'] . "\" direccion=\"" . $place['address'] . "\" imagen_url=\"" . $imagen_link . "\" telefono=\"" . $place['phoneNumber'] . "\" como_llegar_url=\"" . $place['website'] . "\" rating=\"" . $place['rating'] . "/5\"]";


                // Verificar si el contenido tiene datos antes de crear el post
                if (!empty($intro) && !empty($response) && !empty($faqs)) {
                    // Crear el post en WordPress
                    $post_data = array(
                        'post_title' => sanitize_text_field($place['title']),
                        'post_content' => $intro . "\n\n" . $shortcode_de_resena . "\n\n" . $response . "\n\n<h2>" . sanitize_text_field($faqs_title) . "</h2>" . $faqs,
                        'post_status' => sanitize_text_field(get_option('tag_post_status', 'draft')),
                        'post_category' => array(get_cat_ID($selectedCategory))
                    );

                    $post_id = wp_insert_post($post_data);

                    if (!is_wp_error($post_id)) {
                        error_log("Post creado exitosamente con el título: '" . $place['title'] . "'");
                        $created_titles[] = trim($place['title']);
                         // Incrementar el contador de posts creados, pero solo si es menor que el límite
                       if ($posts_created < $max_posts_per_run) {
                          $posts_created++;
                         }
                    } else {
                        error_log("Error al crear el post para el título: '" . $place['title'] . "'");
                        $failed_titles[] = trim($place['title']);
                    }

                    update_option('tag_created_titles', $created_titles);
                    update_option('tag_failed_titles', $failed_titles);
                } else {
                    // Manejar caso de contenido vacío
                    error_log("No se puede crear el post, el contenido está vacío para el título: " . esc_html($place['title']));
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
					$serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
                    if (($key = array_search($title, $serper_consulted_titles)) !== false) {
                     unset($serper_consulted_titles[$key]);
                     }
                     update_option('tag_serper_consulted_titles', $serper_consulted_titles);
                }


            }

            // Actualizar la cola eliminando el título principal si se han creado todos los posts posibles
            if ($posts_created >= $max_posts_per_run) {
                error_log("Se completó la creación de posts para el título: '" . $titulo . "'");
            } else {
                error_log("Se procesaron todos los lugares posibles para el título: '" . $titulo . "'");
            }
        }

        update_option('tag_article_queue', $queue); // Guardar la cola actualizada
    }
}

// Función para verificar si es nicho directorio
function is_directorio_niche() {
    $is_directorio = get_option('tag_nicho_directorio');
    return $is_directorio === 'si'; // Ajusta 'si' según el valor que indica que es nicho directorio
}

function tag_process_directorio_queue() {
    // Verificar si la configuración es de nicho de directorio
    if (!is_directorio_niche()) {
        return; // Detener la función si no es nicho de directorio
    }

    // --- Verificar si las API Keys de Serper están configuradas ---
    $serper_api_keys = get_option('tag_serper_api_keys');
    if (empty($serper_api_keys)) {
        // Manejar el caso en que las API Keys de Serper no están configuradas
        error_log("Error: Las API Keys de Serper son obligatorias para el nicho de directorio.");
        // Opcional: puedes mostrar un mensaje de error en la interfaz del plugin aquí
        return; // Detener la ejecución de la función
    }
    // -------------------------------------------------------------

    $queue = get_option('tag_article_queue', array());
    $failed_titles = get_option('tag_failed_titles', array());
    // Array para almacenar los títulos consultados a Serper
    $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());

    if (!empty($queue)) {
        $title = array_shift($queue);
        $created_titles = get_option('tag_created_titles', array());
        $delay = intval(get_option('tag_article_delay'));
        $categories = explode('|', sanitize_text_field(get_option('tag_categories')));
        $Tematica = get_option('tag_tematica_directorio', ''); // Obtener la temática, valor por defecto vacío

        // --- Verificar si ya existe un post con el mismo título ---
        $existing_post = get_page_by_title( $title, OBJECT, 'post' );
        if ( $existing_post ) {
            error_log("Ya existe un post con el título: '$title'");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }
		
		// --- Verificar si el título ya ha sido consultado a Serper ---
        if (in_array($title, $serper_consulted_titles)) {
            error_log("El título '$title' ya ha sido consultado a Serper.");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }
        // -------------------------------------------------------

        // Obtener el idioma seleccionado
        $language = get_option('tag_language', 'Español');

        // Ajustar el idioma para las variantes del español
        $spanishVariants = array(
            'Español (Perú)', 'Español (México)', 'Español (Argentina)', 'Español (Chile)',
            'Español (Colombia)', 'Español (Ecuador)', 'Español (Venezuela)', 'Español (Guatemala)',
            'Español (Cuba)', 'Español (Bolivia)', 'Español (Haití)', 'Español (República Dominicana)',
            'Español (Honduras)', 'Español (Paraguay)', 'Español (Nicaragua)', 'Español (El Salvador)',
            'Español (Costa Rica)', 'Español (Puerto Rico)', 'Español (Panamá)', 'Español (Uruguay)',
            'Español (Jamaica)', 'Español (Trinidad y Tobago)', 'Español (Belice)'
        );
        if (in_array($language, $spanishVariants)) {
            $language = 'Español';
        }

        // Obtener el modelo seleccionado
        $model = get_option('tag_model', 'meta-llama/Llama-3-70b-chat-hf');

        // Definir los prompts.
        $intro_prompt = get_option('tag_intro_prompt', "Crea una introducción de 100 palabras, en idioma $language, para un artículo sobre: '$title'. No incluyas ningún otro texto antes de la introducción. No saludes, ni respondas nada más, ni hagas ninguna traducción innecesaria. No hables ningún otro idioma que no fuera solo $language.");
        $faqs_prompt = get_option('tag_faqs_prompt', "Solo Crea unicamente 4 Preguntas Frecuentes en $language, acerca de '$title'. Formatea cada pregunta como subtítulo H3 en HTML '<h3></h3>' y responde inmediatamente después de cada pregunta con un párrafo extenso en $language, utilizando negritas en HTML '<strong></strong>' para las palabras más relevantes. No incluyas ningún otro texto antes de las preguntas. No saludes antes de las preguntas, no hables ningún otro idioma que no fuera solo $language.");
		$system_prompt = get_option('tag_system_prompt', "Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '. ");
		
		$intro_prompt = str_replace(['$title', '$language'], [$title, $language], $intro_prompt);
		$faqs_prompt = str_replace(['$title', '$language'], [$title, $language], $faqs_prompt);
		$system_prompt = str_replace('$language', $language, $system_prompt);

        // --- Llamar a las funciones de Serper solo si hay API keys configuradas ---
        if (!empty($serper_api_keys)) {
            $youtube_video_url = tag_call_google_serp_dev_videos($title);
            $places_data = tag_call_google_maps_dev($title); // Obtener datos de lugares

            // --- Agregar el título a la lista de títulos consultados a Serper ---
            $serper_consulted_titles[] = $title;
            update_option('tag_serper_consulted_titles', $serper_consulted_titles);

        } else {
            $youtube_video_url = null;
            $places_data = null;
        }

        // ----------------------------------------------------------------------

        // Datos para la llamada a la API.
        $data_intro = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $intro_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 500,
        );
		
		// Datos para la llamada a la API.
        $prompt_h2_2 = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => 'Crea 1 subtítulo H2 que aborde sobre la tematica: ' . $title . ' en ' . $language . '. Coloca ese subtítulo en HTML "<h2></h2>". no hables ningun otro idioma que no fuera solo ' . $language . '')
            ),
            'temperature' => 0.90,
            'max_tokens' => 500,
        );

        $data_faqs = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $faqs_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 2000,
        );

        // Realizar solicitudes a la API para intro y faqs.
        $response_intro = tag_make_api_request($data_intro);
        $response_faqs = tag_make_api_request($data_faqs);
		$prompt_h2_2 = tag_make_api_request($prompt_h2_2);

        // Verificar si alguna de las respuestas es un error o está vacía
        if (is_wp_error($response_intro) || is_wp_error($response_faqs) || is_wp_error($prompt_h2_2) || 
            empty($response_intro) || empty($response_faqs) || empty($prompt_h2_2)) {
    
            // Obtener la lista actual de títulos fallidos
            $failed_titles = get_option('tag_failed_titles', array());

            // Agregar el título fallido a la lista
            $failed_titles[] = $title; // Usar la variable $title que contiene el título fallido

            // Actualizar la opción con la nueva lista de títulos fallidos
            update_option('tag_failed_titles', array_unique($failed_titles));
    
            // Actualizar la cola de artículos
            $queue = get_option('tag_article_queue', array());

            // Eliminar el título fallido de la cola
            if (($key = array_search($title, $queue)) !== false) {
                unset($queue[$key]);
            }

            // Guardar la cola actualizada
            update_option('tag_article_queue', $queue);

            // Detener el proceso para evitar más operaciones con este título fallido
            return;
        }

        $intro = tag_filter_content($response_intro->choices[0]->message->content);
        $intro = str_replace($title, '', $intro);
		$prompt_h2_2 = tag_filter_content($prompt_h2_2->choices[0]->message->content);
        $faqs = tag_filter_content($response_faqs->choices[0]->message->content);
        $faqs = tag_remove_underscores($faqs);

        // Obtener el título del H2 de Preguntas Frecuentes
        $faqs_title = get_option('tag_faqs_title', 'Preguntas Frecuentes');

        // Seleccionar una categoría aleatoria correctamente
        $randomCategoryIndex = array_rand($categories);
        $selectedCategory = $categories[$randomCategoryIndex];

        // --- Generar contenido para nicho directorio ---
        if (!empty($places_data)) {
            $datos_places = "";
            foreach ($places_data as $place) {
                // Generar la reseña para el lugar (para el post principal)
                $review_place_prompt = "Crea una reseña corta para: '" . $place['title'] . "' a base de la tematica:' . $Tematica . '. Puedes usar estos datos para la reseña: " . $place['address'] . ", " . $place['phoneNumber'] . ", " . $place['website'] . " y " . $place['rating'] . ". No hables ningun otro idioma que no fuera solo $language. Máximo 200 palabras.";
                $data_review_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => $system_prompt),
                        array('role' => 'user', 'content' => $review_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 1000,
                );
                $response_review_place = tag_make_api_request($data_review_place);

                if (is_wp_error($response_review_place)) {
                    // Manejar errores de la API
                    error_log("Error en la generación de la reseña del lugar: " . $response_review_place->get_error_message());
                    continue;
                }

                $review_place = tag_filter_content($response_review_place->choices[0]->message->content);
                $review_place = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $review_place);

                // Obtener la imagen para el lugar
                $imagen_link = tag_call_google_imagen_directorio_dev($place['title']);

                // Crear el shortcode para el lugar
                $shortcode_place = "[hostal_shortcode titulo=\"" . $place['title'] . "\" direccion=\"" . $place['address'] . "\" imagen_url=\"" . $imagen_link . "\" telefono=\"" . $place['phoneNumber'] . "\" como_llegar_url=\"" . $place['website'] . "\" rating=\"" . $place['rating'] . "/5\"]";

                // Agregar la información al contenido del post principal
                $datos_places .= "<h3>" . $place['title'] . "</h3>\n";
                $datos_places .= "$shortcode_place\n";
                $datos_places .= $review_place . "\n"; 
            }

            // Verificar que el contenido no esté vacío antes de crear el post
            if (!empty($intro) && !empty($prompt_h2_2) && !empty($datos_places) && !empty($faqs)) {
                // Crear el post principal del directorio
                $post_data = array(
                    'post_title'    => sanitize_text_field($title),
                    'post_content'  => wp_kses_post("$intro\n\n$youtube_video_url\n\n$prompt_h2_2\n\n$datos_places\n\n<h2>$faqs_title</h2>\n$faqs"),
                    'post_status'   => get_option('tag_post_status', 'publish'),
                    'post_author'   => 1,
                    'post_category' => array(get_cat_ID($selectedCategory))
                );

                $post_id = wp_insert_post($post_data);

                if (is_wp_error($post_id)) {
                    // Manejar errores al crear el post
                    error_log("Error al crear el post principal del directorio: " . $post_id->get_error_message());
                    // Agregar el título a la lista de fallidos
                    $failed_titles[] = trim($title);
                    update_option('tag_failed_titles', array_unique($failed_titles));
					$serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
                    if (($key = array_search($title, $serper_consulted_titles)) !== false) {
                     unset($serper_consulted_titles[$key]);
                    }
                    update_option('tag_serper_consulted_titles', $serper_consulted_titles);
                } else {
                    // Agregar título a la lista de títulos creados.
                    $created_titles[] = trim($title);
                    update_option('tag_created_titles', array_unique($created_titles));
                    // Registrar el éxito en los logs (opcional)
                    error_log("Post creado con éxito: " . get_edit_post_link($post_id) . " - " . esc_html($title));
                }
            } else {
                // Manejar caso de contenido vacío
                error_log("No se puede crear el post principal del directorio, el contenido está vacío para el título: " . esc_html($title));

                // Agregar el título a la lista de fallidos
                $failed_titles[] = trim($title);
                update_option('tag_failed_titles', array_unique($failed_titles));
				$serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
                if (($key = array_search($title, $serper_consulted_titles)) !== false) {
                   unset($serper_consulted_titles[$key]);
                }
                update_option('tag_serper_consulted_titles', $serper_consulted_titles);
            }

            // Actualizar la cola
            update_option('tag_article_queue', $queue);
        }
    } 
}

function tag_process_article_queue() {
    // Verificar si la configuración NO es de nicho de directorio NI de reseñas individuales NI DE AMAZON SIN API
    if (is_directorio_niche() || is_reseñas_individuales_niche() || is_amazon_sin_api_niche()) {
        return;
    }

    // Array para almacenar los títulos consultados a Serper
    $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());

    $queue = get_option('tag_article_queue', array());
    $failed_titles = get_option('tag_failed_titles', array());

    if (!empty($queue)) {
        $title = array_shift($queue);
        $created_titles = get_option('tag_created_titles', array());
        $delay = intval(get_option('tag_article_delay'));
        $categories = explode('|', sanitize_text_field(get_option('tag_categories')));

        // --- Verificar si ya existe un post con el mismo título ---
        $args = array(
          'post_type' => 'post', // Especificar el tipo de post como 'post'
          'title' => $title, // Buscar por el título
          'posts_per_page' => 1 // Limitar la búsqueda a un solo post
		);
        $existing_post = get_posts($args);
        if (!empty($existing_post)) {
            error_log("Ya existe un post con el título: '$title'");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }

        // --- Verificar si el título ya ha sido consultado a Serper ---
        if (in_array($title, $serper_consulted_titles)) {
            error_log("El título '$title' ya ha sido consultado a Serper.");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }

        // Obtener el idioma seleccionado
        $language = get_option('tag_language', 'Español');

        // Ajustar el idioma para las variantes del español
        $spanishVariants = array(
            'Español (Perú)', 'Español (México)', 'Español (Argentina)', 'Español (Chile)',
            'Español (Colombia)', 'Español (Ecuador)', 'Español (Venezuela)', 'Español (Guatemala)',
            'Español (Cuba)', 'Español (Bolivia)', 'Español (Haití)', 'Español (República Dominicana)',
            'Español (Honduras)', 'Español (Paraguay)', 'Español (Nicaragua)', 'Español (El Salvador)',
            'Español (Costa Rica)', 'Español (Puerto Rico)', 'Español (Panamá)', 'Español (Uruguay)',
            'Español (Jamaica)', 'Español (Trinidad y Tobago)', 'Español (Belice)'
        );
        if (in_array($language, $spanishVariants)) {
            $language = 'Español';
        }

        // Obtener el modelo seleccionado
        $model = get_option('tag_model', 'meta-llama/Llama-3-70b-chat-hf');

        // Definir los prompts.
        $intro_prompt = get_option('tag_intro_prompt', "Crea una introducción de 100 palabras, en idioma $language, para un artículo sobre: '$title'. No incluyas ningún otro texto antes de la                 introducción. No saludes, ni respondas nada más, ni hagas ninguna traducción innecesaria. No hables ningún otro idioma que no fuera solo $language.");
        $subtitles_prompt = get_option('tag_subtitles_prompt', "Crea 1 subtítulo H2 relacionado a la temática: '$title' en $language. Coloca ese subtítulo en HTML '<h2></h2>' y luego responde de forma detallada en $language y agrega también 5 Subtítulos H3 informacionales en $language sobre '$title' en HTML '<h3></h3>' y responde cada Subtítulo h3 de forma detallada y añade una tabla con el formato: '<table></table>' y pon en negrita en HTML '<strong></strong>' las palabras más relevantes en $language y no vayas a añadir una conclusión final, no hables ningún otro idioma que no fuera solo $language.");
        $faqs_prompt = get_option('tag_faqs_prompt', "Solo Crea unicamente 4 Preguntas Frecuentes en $language, acerca de '$title'. Formatea cada pregunta como subtítulo H3 en HTML '<h3></h3>' y responde inmediatamente después de cada pregunta con un párrafo extenso en $language, utilizando negritas en HTML '<strong></strong>' para las palabras más relevantes. No incluyas ningún otro texto antes de las preguntas. No saludes antes de las preguntas, no hables ningún otro idioma que no fuera solo $language.");
        $system_prompt = get_option('tag_system_prompt', "Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '. ");

        $intro_prompt = str_replace(['$title', '$language'], [$title, $language], $intro_prompt);
        $subtitles_prompt = str_replace(['$title', '$language'], [$title, $language], $subtitles_prompt);
        $faqs_prompt = str_replace(['$title', '$language'], [$title, $language], $faqs_prompt);
        $system_prompt = str_replace('$language', $language, $system_prompt); // Reemplazar $language en $system_prompt

        // --- Llamar a las funciones de Serper solo si hay API keys configuradas ---
        $serper_api_keys = get_option('tag_serper_api_keys');
        if (!empty($serper_api_keys)) {
            $related_questions = tag_call_google_serp_dev($title);
            $youtube_video_url = tag_call_google_serp_dev_videos($title);

            // --- Agregar el título a la lista de títulos consultados a Serper ---
            $serper_consulted_titles[] = $title;
            update_option('tag_serper_consulted_titles', $serper_consulted_titles);

        } else {
            $related_questions = null;
            $youtube_video_url = null;
        }
        // ----------------------------------------------------------------------

        // Datos para la llamada a la API.
        $data_intro = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $intro_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 500,
        );

        // Datos para la llamada a la API para determinar la categoría.
        $data_categoria = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => "Determina la categoría más adecuada para el artículo: '$title'. Las categorías posibles son: " . implode('|', $categories) . ". No crees ni respondas, solo elige una de estas: " . implode('|', $categories))
            ),
            'temperature' => 0.75,
            'max_tokens' => 2000,
        );

        $data_subtitles = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $subtitles_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 2500,
        );

        $data_faqs = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $faqs_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 2000,
        );

        // Realizar solicitudes a la API.
        $response_intro = tag_make_api_request($data_intro);
        $response_subtitles = tag_make_api_request($data_subtitles);
        $response_faqs = tag_make_api_request($data_faqs);
        $response_categoria = tag_make_api_request($data_categoria);

        // Verificar si alguna de las respuestas es un error o está vacía
        if (is_wp_error($response_intro) || is_wp_error($response_faqs) || is_wp_error($response_categoria) || is_wp_error($response_subtitles) ||
            empty($response_intro) || empty($response_faqs) || empty($response_categoria) || empty($response_subtitles)) {

            // Obtener la lista actual de títulos fallidos
            $failed_titles = get_option('tag_failed_titles', array());

            // Agregar el título fallido a la lista
            $failed_titles[] = $title; // Usar la variable $title que contiene el título fallido

            // Actualizar la opción con la nueva lista de títulos fallidos
            update_option('tag_failed_titles', array_unique($failed_titles));

            // Actualizar la cola de artículos
            $queue = get_option('tag_article_queue', array());

            // Eliminar el título fallido de la cola
            if (($key = array_search($title, $queue)) !== false) {
                unset($queue[$key]);
            }

            // Guardar la cola actualizada
            update_option('tag_article_queue', $queue);

            // Detener el proceso para evitar más operaciones con este título fallido
            return;
        }

        $intro = tag_filter_content($response_intro->choices[0]->message->content);
        $intro = str_replace($title, '', $intro);
        $subtitles = tag_filter_content($response_subtitles->choices[0]->message->content);
        $faqs = tag_filter_content($response_faqs->choices[0]->message->content);
        $categoria_elegida = tag_filter_content($response_categoria->choices[0]->message->content);

        // Quitar caracteres "_" y reemplazarlos con un espacio
        $subtitles = tag_remove_underscores($subtitles);
        $faqs = tag_remove_underscores($faqs);

        // Obtener el título del H2 de Preguntas Frecuentes
        $faqs_title = get_option('tag_faqs_title', 'Preguntas Frecuentes');

        // Obtener la ID de la categoría elegida por la IA
        $selected_category_id = get_cat_ID($categoria_elegida);

        // Si la categoría no existe, usar una categoría aleatoria
        if (!$selected_category_id) {
            $randomCategoryIndex = array_rand($categories);
            $selectedCategory = $categories[$randomCategoryIndex];
            $selected_category_id = get_cat_ID($selectedCategory);
        }

        // --- Generar respuestas para las preguntas de Serper con Together (solo si hay preguntas) ---
        $questions_and_answers = "";
        if ($related_questions) {
            foreach ($related_questions as $question) {
                // Generar la respuesta con Together
                $question_prompt = get_option('tag_question_prompt', "Por favor, no me saludes, Solo Responde Detalladamente en: '{$language}', la siguiente pregunta: {$question}. Y agrega también 3 Subtítulos H3 Relacionados en '{$language}' sobre {$question} en HTML '<h3></h3>' y responde cada Subtítulo h3 de forma detallada con un párrafo y un formato lista para enriquecer el texto: '<ol><li></li><li></li><li></li></ol>', en '{$language}', y pon en negrita en HTML '<strong></strong>' las palabras más relevantes. No saludes al finalizar, NO HAGAS NINGUNA CONCLUSION, no hables ningún otro idioma que no fuera solo '{$language}'.");
                $question_prompt = str_replace(['$question', '$language'], [$question, $language], $question_prompt);

                $data_question = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => $system_prompt),
                        array('role' => 'user', 'content' => $question_prompt)
                    ),
                    'temperature' => 0.90, // Puedes ajustar la temperatura
                    'max_tokens' => 2000, // Puedes ajustar el número máximo de tokens
                );
                $response_question = tag_make_api_request($data_question);
                if (is_wp_error($response_question)) {
                    error_log("Error en la generación de la respuesta para la pregunta: " . $question . " - " . $response_question->get_error_message());
                    continue;
                }
                $answer = tag_filter_content($response_question->choices[0]->message->content);
                $answer = str_replace($question, '', $answer);

                // Eliminar todas las preguntas de $related_questions de la respuesta:
                foreach ($related_questions as $q) {
                    $answer = str_replace($q, '', $answer);
                }

                // Obtener la imagen relacionada (solo si hay API keys configuradas)
                if (!empty($serper_api_keys)) {
                    $image_url = tag_call_google_imagen_dev($question);
                } else {
                    $image_url = null;
                }
                $image_html = $image_url ? "<p style='text-align: center;'><img src='" . esc_url($image_url) . "' style='display: block; margin: 0 auto;'></p>" : "";

                // Combinar la pregunta, la imagen y la respuesta
                $questions_and_answers .= "<h2>" . esc_html($question) . "</h2>" . $image_html . $answer;
            }
        }
        // -------------------------------------------------------------------------------------------


        // Crear el post en WordPress solo si el contenido no está vacío
        if (!empty($intro) && !empty($faqs) && !empty($subtitles)) {
            // Preparar los datos del post
            $post_data = array(
                'post_title' => sanitize_text_field($title),
                'post_content' => wp_kses_post("$intro\n\n$youtube_video_url\n\n$subtitles\n\n$questions_and_answers\n\n<h2>$faqs_title</h2>\n$faqs"),
                'post_status' => get_option('tag_post_status', 'publish'), // Obtener el estado del post
                'post_author' => 1, // ID del autor. Cambiar según sea necesario.
                'post_category' => array(get_cat_ID($categoria_elegida)) // Asignar la categoría por ID usando get_cat_ID
            );

            // Insertar el post
            $post_id = wp_insert_post($post_data);

            // Manejar el resultado de la inserción
            if (is_wp_error($post_id)) {
                // Manejar errores al crear el post
                error_log("Error al crear el post: " . $post_id->get_error_message());

                // Agregar el título a la lista de fallidos
                $failed_titles[] = trim($title);
                update_option('tag_failed_titles', array_unique($failed_titles));
				
        $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
        if (($key = array_search($title, $serper_consulted_titles)) !== false) {
            unset($serper_consulted_titles[$key]);
        }
        update_option('tag_serper_consulted_titles', $serper_consulted_titles);
            } else {
                // Agregar el título a la lista de títulos creados
                $created_titles[] = trim($title);
                update_option('tag_created_titles', array_unique($created_titles));

                // Registrar el éxito en los logs (opcional)
                error_log("Post creado con éxito: " . get_edit_post_link($post_id) . " - " . esc_html($title));
            }
        } else {
            // Manejar caso de contenido vacío
            error_log("No se puede crear el post, el contenido está vacío para el título: " . esc_html($title));

            // Agregar el título a la lista de fallidos
            $failed_titles[] = trim($title);
            update_option('tag_failed_titles', array_unique($failed_titles));
			
			$serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
        if (($key = array_search($title, $serper_consulted_titles)) !== false) {
            unset($serper_consulted_titles[$key]);
        }
        update_option('tag_serper_consulted_titles', $serper_consulted_titles);
        }

        // Actualizar la cola
        update_option('tag_article_queue', $queue);
    }
}

// Función para verificar si es nicho amazon sin api
function is_amazon_sin_api_niche() {
    $is_amazon = get_option('tag_amazon_sin_api_niche');
    return $is_amazon === 'si'; // Ajusta 'si' según el valor que indica que es nicho amazon sin api
}

function tag_process_amazon_sin_api_queue() {
    // Verificar si la configuración es de nicho de amazon sin api
    if (!is_amazon_sin_api_niche()) {
        return; // Detener la función si no es nicho de amazon sin api
    }

    // Variable global para almacenar el último título de cola procesado
    global $tag_last_processed_title;

    // Array para almacenar los títulos consultados a Serper
    $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());

    $queue = get_option('tag_article_queue', array());
    $failed_titles = get_option('tag_failed_titles', array());

    if (!empty($queue)) {
        $title = array_shift($queue);
        $created_titles = get_option('tag_created_titles', array());
        $delay = intval(get_option('tag_article_delay'));
        $categories = explode('|', sanitize_text_field(get_option('tag_categories')));

        // --- Verificar si ya existe un post con el mismo título ---
        $existing_post = get_page_by_title($title, OBJECT, 'post');
        if ($existing_post) {
            error_log("Ya existe un post con el título: '$title'");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }

        // --- Verificar si el título ya ha sido consultado a Serper ---
        if (in_array($title, $serper_consulted_titles)) {
            error_log("El título '$title' ya ha sido consultado a Serper.");
            update_option('tag_article_queue', $queue); // Actualizar la cola sin procesar este título
            return;
        }

        $language = get_option('tag_language', 'Español');
        $id_afiliado = get_option('tag_amazon_affiliate_id');
        $domain_suffix = get_amazon_domain_suffix();

        // Ajustar el idioma para las variantes del español
        $spanishVariants = array(
            'Español (Perú)', 'Español (México)', 'Español (Argentina)', 'Español (Chile)',
            'Español (Colombia)', 'Español (Ecuador)', 'Español (Venezuela)', 'Español (Guatemala)',
            'Español (Cuba)', 'Español (Bolivia)', 'Español (Haití)', 'Español (República Dominicana)',
            'Español (Honduras)', 'Español (Paraguay)', 'Español (Nicaragua)', 'Español (El Salvador)',
            'Español (Costa Rica)', 'Español (Puerto Rico)', 'Español (Panamá)', 'Español (Uruguay)',
            'Español (Jamaica)', 'Español (Trinidad y Tobago)', 'Español (Belice)'
        );
        if (in_array($language, $spanishVariants)) {
            $language = 'Español';
        }

        // Obtener el modelo seleccionado
        $model = get_option('tag_model', 'meta-llama/Llama-3-70b-chat-hf');

        // Definir los prompts.
        $intro_prompt = get_option('tag_intro_prompt', "Crea una introducción de 100 palabras, en idioma $language, para un artículo sobre: '$title'. No incluyas ningún otro texto antes de la introducción. No saludes, ni respondas nada más, ni hagas ninguna traducción innecesaria. No hables ningún otro idioma que no fuera solo $language.");
        $faqs_prompt = get_option('tag_faqs_prompt', "Solo Crea unicamente 4 Preguntas Frecuentes en $language, acerca de '$title'. Formatea cada pregunta como subtítulo H3 en HTML '<h3></h3>' y responde inmediatamente después de cada pregunta con un párrafo extenso en $language, utilizando negritas en HTML '<strong></strong>' para las palabras más relevantes. No incluyas ningún otro texto antes de las preguntas. No saludes antes de las preguntas, no hables ningún otro idioma que no fuera solo $language.");
        $system_prompt = get_option('tag_system_prompt', "Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '. ");

        $intro_prompt = str_replace(['$title', '$language'], [$title, $language], $intro_prompt);
        $faqs_prompt = str_replace(['$title', '$language'], [$title, $language], $faqs_prompt);
        $system_prompt = str_replace('$language', $language, $system_prompt); // Reemplazar $language en $system_prompt

        // --- Llamar a las funciones de Serper solo si hay API keys configuradas ---
        $serper_api_keys = get_option('tag_serper_api_keys');
        if (!empty($serper_api_keys)) {
            $related_questions = tag_call_google_serp_dev($title);
            $youtube_video_url = tag_call_google_serp_dev_videos($title);

            // --- Agregar el título a la lista de títulos consultados a Serper ---
            $serper_consulted_titles[] = $title;
            update_option('tag_serper_consulted_titles', $serper_consulted_titles);

        } else {
            $related_questions = null;
            $youtube_video_url = null;
        }
        // ----------------------------------------------------------------------

        // Datos para la llamada a la API.
        $data_intro = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $intro_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 500,
        );

        // Datos para la llamada a la API para determinar la categoría.
        $data_categoria = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => "Determina la categoría más adecuada para el artículo: '$title'. Las categorías posibles son: " . implode('|', $categories) . ". No crees ni respondas, solo elige una de estas: " . implode('|', $categories))
            ),
            'temperature' => 0.75,
            'max_tokens' => 2000,
        );

        // Datos para la llamada a la API.
        $prompt_h2_2 = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => 'Crea 1 subtítulo H2 en ' . $language . ' que comience con una de las siguientes frases: "Los Mejores", "Top Reseñas", "Las Mejores Opciones", seguido del tema: ' . $title . '. Devuélvelo en formato HTML "<h2></h2>" y solo en ' . $language . '')
            ),
            'temperature' => 0.90,
            'max_tokens' => 500,
        );

        $data_faqs = array(
            'model' => $model,
            'messages' => array(
                array('role' => 'system', 'content' => $system_prompt),
                array('role' => 'user', 'content' => $faqs_prompt)
            ),
            'temperature' => 0.90,
            'max_tokens' => 2000,
        );

        // Realizar solicitudes a la API.
        $response_intro = tag_make_api_request($data_intro);
        $prompt_h2 = tag_make_api_request($prompt_h2_2);
        $response_faqs = tag_make_api_request($data_faqs);
        $response_categoria = tag_make_api_request($data_categoria);

        // Generar el título SEO del POST con la IA
        $titulo_seo_post_prompt = "Crea un título SEO optimizado no muy largo para un artículo sobre ' . $title . ' en ' . $language . '. NO SALUDES AL FINALIZAR. solo devuelve el titulo creado nada mas. no hables ningun otro idioma que no fuera solo ' . $language . '.";
        $data_titulo_seo_post = [
            'model' => $model,
            'messages' => [
                ['role' => 'system', 'content' => $system_prompt],
                ['role' => 'user', 'content' => $titulo_seo_post_prompt]
            ],
            'temperature' => 0.75,
            'max_tokens' => 2000,
        ];
        $response_titulo_seo_post = tag_make_api_request($data_titulo_seo_post);

        if (is_wp_error($response_titulo_seo_post)) {
            error_log("Error al generar el título SEO del post: " . $response_titulo_seo_post->get_error_message());
            // Manejo de errores...
        } else {
            $titulo_seo_post = tag_filter_content($response_titulo_seo_post->choices[0]->message->content);
            $titulo_seo_post = str_replace('"', '', $titulo_seo_post);
        }

        // Verificar si alguna de las respuestas es un error o está vacía
        if (is_wp_error($response_intro) || is_wp_error($response_faqs) || is_wp_error($response_categoria) || is_wp_error($prompt_h2) || is_wp_error($response_titulo_seo_post) ||
            empty($response_intro) || empty($response_faqs) || empty($response_categoria) || empty($prompt_h2) || empty($titulo_seo_post)) {

            // Obtener la lista actual de títulos fallidos
            $failed_titles = get_option('tag_failed_titles', array());

            // Agregar el título fallido a la lista
            $failed_titles[] = $title; // Usar la variable $title que contiene el título fallido

            // Actualizar la opción con la nueva lista de títulos fallidos
            update_option('tag_failed_titles', array_unique($failed_titles));

            // Actualizar la cola de artículos
            $queue = get_option('tag_article_queue', array());

            // Eliminar el título fallido de la cola
            if (($key = array_search($title, $queue)) !== false) {
                unset($queue[$key]);
            }

            // Guardar la cola actualizada
            update_option('tag_article_queue', $queue);

            // Detener el proceso para evitar más operaciones con este título fallido
            return;
        }

        $intro = tag_filter_content($response_intro->choices[0]->message->content);
        $intro = str_replace($title, '', $intro);
        $prompt_h2 = tag_filter_content($prompt_h2->choices[0]->message->content);
        $prompt_h2_arreglado = preg_replace('/\b(2021|2022|2023)\b/', '2024', $prompt_h2);
        $faqs = tag_filter_content($response_faqs->choices[0]->message->content);
        $faqs = tag_remove_underscores($faqs);
        $categoria_elegida = tag_filter_content($response_categoria->choices[0]->message->content);

        // Obtener el título del H2 de Preguntas Frecuentes
        $faqs_title = get_option('tag_faqs_title', 'Preguntas Frecuentes');

        // Obtener la ID de la categoría elegida por la IA
        $selected_category_id = get_cat_ID($categoria_elegida);

        // Si la categoría no existe, usar una categoría aleatoria
        if (!$selected_category_id) {
            $randomCategoryIndex = array_rand($categories);
            $selectedCategory = $categories[$randomCategoryIndex];
            $selected_category_id = get_cat_ID($selectedCategory);
        }

        // --- Buscar productos de Amazon ---


        if ($language === 'Japonés' || $language === 'Árabe' || $language === 'Turco' || $language === 'Polaco' || $language === 'Neerlandés' || $language === 'Sueco' || $language === 'Alemán' || $language === 'Francés') {
            // --- Traducir el título al inglés si el idioma es japonés ---
            $translation_prompt = "Traduce el siguiente texto al inglés: '$title'. No saludes AL EMPEZAR, NO SALUDES al finalizar, solo devuelve la traducción.";
            $data_translation = [
                'model' => $model,
                'messages' => [
                    ['role' => 'system', 'content' => 'Eres un traductor experto ingles.'],
                    ['role' => 'user', 'content' => $translation_prompt]
                ],
                'temperature' => 0.90,
                'max_tokens' => 1500,
            ];
            $response_translation = tag_make_api_request($data_translation);

            if (is_wp_error($response_translation)) {
                error_log("Error al traducir el título: " . $response_translation->get_error_message());
                // Manejo de errores... (puedes optar por no buscar productos en este caso)
            } else {
                $english_title = tag_filter_content($response_translation->choices[0]->message->content);
                $english_title = str_replace('"', '', $english_title);
                $products = search_amazon($english_title); // Buscar en Amazon con el título en inglés
            }
        } else {
            $products = search_amazon($title); // Buscar en Amazon con el título original
        }
        $product_list = [];
        if (!empty($products)) {
            foreach ($products as $product) {
                try {
                    if (isset($product['url']) && strpos($product['url'], '/dp/') !== false && isset($product['title'])) {
                        $domain_suffix = get_amazon_domain_suffix();
                        $asin = explode('/dp/', $product['url'])[1];
                        $asin = explode('/', $asin)[0];
                        $apilink = "https://www.amazon.{$domain_suffix}/dp/{$asin}?tag={$id_afiliado}"; // Reemplaza {id_afiliado} con tu ID de afiliado
                        $stars = $product['stars'] ?? 'N/A';
                        $total_reviews = $product['total_reviews'] ?? '5/5';

                        // Limpiar el título del producto
                        $clean_title = str_replace(['|', '"', '/', '{', '}', '[', ']', '(', ')'], '', $product['title']);

                        // Construir el shortcode
                        $product_shortcode = "[amazon nombre=\"{$clean_title}\" enlace=\"{$apilink}\" imagen=\"{$product['image']}\"]";

                        // Solo agregar el shortcode a la lista
                        $product_list[] = $product_shortcode;
                    }
                } catch (Exception $e) {
                    continue;
                }
            }

            // Unir todos los shortcodes en una sola cadena
            $Hamazon = implode("\n", $product_list);
        }

        // --- Generar respuestas para las preguntas de Serper con Together (solo si hay preguntas) ---
        $questions_and_answers = "";
        if ($related_questions) {
            foreach ($related_questions as $question) {
                // Generar la respuesta con Together
                $question_prompt = get_option('tag_question_prompt', "Por favor, no me saludes, Solo Responde Detalladamente en: '{$language}', la siguiente pregunta: {$question}. Y agrega también 3 Subtítulos H3 Relacionados en '{$language}' sobre {$question} en HTML '<h3></h3>' y responde cada Subtítulo h3 de forma detallada con un párrafo y un formato lista para enriquecer el texto: '<ol><li></li><li></li><li></li></ol>', en '{$language}', y pon en negrita en HTML '<strong></strong>' las palabras más relevantes. No saludes al finalizar, NO HAGAS NINGUNA CONCLUSION, no hables ningún otro idioma que no fuera solo '{$language}'.");
                $question_prompt = str_replace(['$question', '$language'], [$question, $language], $question_prompt);
                $data_question = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => $system_prompt),
                        array('role' => 'user', 'content' => $question_prompt)
                    ),
                    'temperature' => 0.90, // Puedes ajustar la temperatura
                    'max_tokens' => 2000, // Puedes ajustar el número máximo de tokens
                );
                $response_question = tag_make_api_request($data_question);
                if (is_wp_error($response_question)) {
                    error_log("Error en la generación de la respuesta para la pregunta: " . $question . " - " . $response_question->get_error_message());
                    continue;
                }
                $answer = tag_filter_content($response_question->choices[0]->message->content);
                $answer = str_replace($question, '', $answer);
                // Eliminar todas las preguntas de $related_questions de la respuesta:
                foreach ($related_questions as $q) {
                    $answer = str_replace($q, '', $answer);
                }
                // Obtener la imagen relacionada (solo si hay API keys configuradas)
                if (!empty($serper_api_keys)) {
                    $image_url = tag_call_google_imagen_dev($question);
                } else {
                    $image_url = null;
                }
                $image_html = $image_url ? "<p style='text-align: center;'><img src='" . esc_url($image_url) . "' style='display: block; margin: 0 auto;'></p>" : "";

                // Combinar la pregunta, la imagen y la respuesta
                $questions_and_answers .= "<h2>" . esc_html($question) . "</h2>" . $image_html . $answer;
            }
        }
        // -------------------------------------------------------------------------------------------

        // --- Verificar si el título de la cola ya ha sido procesado ---
        if ($title === $tag_last_processed_title) {
            error_log("El título de la cola '$title' ya ha sido procesado en esta ejecución.");
            update_option('tag_article_queue', $queue); // Actualizar la cola
            return; // Detener la función
        }

        // --- Si $Hamazon está vacío, vaciar también $prompt_h2 ---
        if (empty($Hamazon)) {
            $prompt_h2_arreglado = "";
        }

        // Verificar si el contenido tiene datos antes de crear el post
        if (!empty($intro) && !empty($questions_and_answers) && !empty($faqs)) {
            // Crear el post en WordPress.
            $post_data = array(
                'post_title'    => sanitize_text_field($titulo_seo_post),
                'post_content'  => wp_kses_post("$intro\n\n$prompt_h2_arreglado\n\n$Hamazon\n\n$questions_and_answers\n\n$youtube_video_url\n\n<h2>$faqs_title</h2>\n$faqs"),
                'post_status'   => get_option('tag_post_status', 'publish'), // Obtener el estado del post
                'post_author'   => 1, // ID del autor. Cambiar según sea necesario.
                'post_category' => array(get_cat_ID($categoria_elegida)) // Asignar la categoría por ID usando get_cat_ID
            );

            // Insertar el post
            $post_id = wp_insert_post($post_data);

            // Manejar el resultado de la inserción
            if (is_wp_error($post_id)) {
                // Manejar errores al crear el post
                error_log("Error al crear el post: " . $post_id->get_error_message());

                // Agregar el título a la lista de fallidos
                $failed_titles[] = trim($title);
                update_option('tag_failed_titles', array_unique($failed_titles));
				
				// *** AÑADIR EL CÓDIGO AQUÍ ***
        // Eliminar el título de la lista de títulos consultados a Serper
        $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
        if (($key = array_search($title, $serper_consulted_titles)) !== false) {
            unset($serper_consulted_titles[$key]);
        }
        update_option('tag_serper_consulted_titles', $serper_consulted_titles);
        // *** FIN DEL CÓDIGO AÑADIDO ***
        // 
            } else {
                // Guardar el título de la cola como último procesado
                $tag_last_processed_title = $title;

                // Agregar título a la lista de títulos creados
                $created_titles[] = trim($title);
                update_option('tag_created_titles', array_unique($created_titles)); // CORREGIDO

                // Registrar el éxito en los logs (opcional)
                error_log("Post creado con éxito: " . get_edit_post_link($post_id) . " - " . esc_html($title));
            }
        } else {
            // Manejar caso de contenido vacío
            error_log("No se puede crear el post, el contenido está vacío para el título: " . esc_html($title));

            // Agregar el título a la lista de fallidos
            $failed_titles[] = trim($title);
            update_option('tag_failed_titles', array_unique($failed_titles));
			
			// *** AÑADIR EL CÓDIGO AQUÍ ***
        // Eliminar el título de la lista de títulos consultados a Serper
        $serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
        if (($key = array_search($title, $serper_consulted_titles)) !== false) {
            unset($serper_consulted_titles[$key]);
        }
        update_option('tag_serper_consulted_titles', $serper_consulted_titles);
        // *** FIN DEL CÓDIGO AÑADIDO ***
        }

        // Actualizar la cola
        update_option('tag_article_queue', $queue);
    }
}

function tag_schedule_article_generation() {
    // Obtén el tiempo de espera de la base de datos
    $delay = get_option('tag_article_delay', 60); // Valor por defecto de 60 segundos si no está configurado

    // Añade o actualiza los eventos cron con el intervalo configurado
    if (!wp_next_scheduled('tag_generate_directorio_cron')) {
        wp_schedule_event(time(), 'custom_interval', 'tag_generate_directorio_cron');
    }
    if (!wp_next_scheduled('tag_generate_articles_cron')) {
        wp_schedule_event(time(), 'custom_interval', 'tag_generate_articles_cron');
    }
    if (!wp_next_scheduled('tag_generate_places_cron')) {
        wp_schedule_event(time(), 'custom_interval', 'tag_generate_places_cron');
    }
    if (!wp_next_scheduled('tag_generate_amazon_sin_api_cron')) { 
        wp_schedule_event(time(), 'custom_interval', 'tag_generate_amazon_sin_api_cron');
    }
}
add_action('wp', 'tag_schedule_article_generation');

function tag_add_cron_interval($schedules) {
    $delay = get_option('tag_article_delay', 60); // Valor por defecto de 60 segundos si no está configurado
    $schedules['custom_interval'] = array(
        'interval' => $delay,
        'display'  => __('Custom Interval')
    );
    return $schedules;
}
add_filter('cron_schedules', 'tag_add_cron_interval');

// Desregistrar el cron que no corresponda al guardar las opciones de nicho
function tag_unschedule_incorrect_cron() {
    if (is_directorio_niche()) {
        // Nicho directorio
        wp_clear_scheduled_hook('tag_generate_articles_cron');
        wp_clear_scheduled_hook('tag_generate_places_cron');
        wp_clear_scheduled_hook('tag_generate_amazon_sin_api_cron');
    } elseif (is_reseñas_individuales_niche()) {
        // Nicho de reseñas individuales
        wp_clear_scheduled_hook('tag_generate_directorio_cron');
        wp_clear_scheduled_hook('tag_generate_articles_cron');
        wp_clear_scheduled_hook('tag_generate_amazon_sin_api_cron');
    } elseif (is_amazon_sin_api_niche()) { 
        // Nicho de Amazon sin API
        wp_clear_scheduled_hook('tag_generate_directorio_cron');
        wp_clear_scheduled_hook('tag_generate_places_cron');
        wp_clear_scheduled_hook('tag_generate_articles_cron'); 
    } else {
        // Si no es ninguno de los nichos anteriores, desprogramar por defecto
        wp_clear_scheduled_hook('tag_generate_directorio_cron');
        wp_clear_scheduled_hook('tag_generate_places_cron');
        wp_clear_scheduled_hook('tag_generate_amazon_sin_api_cron');
    }
}

// Añadir acciones para los tres tipos de nicho
add_action('update_option_tag_nicho_directorio', 'tag_unschedule_incorrect_cron');
add_action('update_option_tag_niche_type', 'tag_unschedule_incorrect_cron');
add_action('update_option_tag_amazon_sin_api_niche', 'tag_unschedule_incorrect_cron');

// Desregistrar eventos cron al desactivar el plugin
function tag_unschedule_article_generation() {
    wp_clear_scheduled_hook('tag_generate_directorio_cron');
    wp_clear_scheduled_hook('tag_generate_articles_cron');
    wp_clear_scheduled_hook('tag_generate_places_cron');
	wp_clear_scheduled_hook('tag_generate_amazon_sin_api_cron');
}
register_deactivation_hook(__FILE__, 'tag_unschedule_article_generation');

// Acciones para ejecutar las funciones de procesamiento de colas
add_action('tag_generate_directorio_cron', 'tag_process_directorio_queue');
add_action('tag_generate_articles_cron', 'tag_process_article_queue');
add_action('tag_generate_places_cron', 'tag_process_places_queue');
add_action('tag_generate_amazon_sin_api_cron', 'tag_process_amazon_sin_api_queue');

// Mostrar la página de administración.
function tag_admin_page() {
    // Obtener los títulos creados almacenados.
    $created_titles = get_option('tag_created_titles', array());
    $api_key = get_option('tag_api_key');
    $delay = get_option('tag_article_delay', 60); // Valor por defecto de 60 segundos (1 minuto).
    $categories = get_option('tag_categories', '');

// Idiomas disponibles
$languages = array(
    'Español' => 'Español',
    'Inglés' => 'Inglés',
    'Turco' => 'Turco',
    'Árabe' => 'Árabe',
    'Hindi' => 'Hindi',
    'Ruso' => 'Ruso',
    'Francés' => 'Francés',
    'Portugués' => 'Portugués',
    'Alemán' => 'Alemán',
    'Polaco' => 'Polaco',
    'Japonés' => 'Japonés',
    'Coreano' => 'Coreano',
    'Sueco' => 'Sueco',
    'Indonesio' => 'Indonesio',
    'Italiano' => 'Italiano',
    'Hebreo' => 'Hebreo',
    'Chino Mandarín' => 'Chino Mandarín',
    'Neerlandés' => 'Neerlandés',
    'Vietnamita' => 'Vietnamita',
    'Sundanés' => 'Sundanés',
    'Español (Perú)' => 'Español (Perú)',
    'Español (México)' => 'Español (México)',
    'Español (Argentina)' => 'Español (Argentina)',
    'Español (Chile)' => 'Español (Chile)',
    'Español (Colombia)' => 'Español (Colombia)',
    'Español (Ecuador)' => 'Español (Ecuador)',
    'Español (Venezuela)' => 'Español (Venezuela)',
    'Español (Guatemala)' => 'Español (Guatemala)',
    'Español (Cuba)' => 'Español (Cuba)',
    'Español (Bolivia)' => 'Español (Bolivia)',
    'Español (Haití)' => 'Español (Haití)',
    'Español (República Dominicana)' => 'Español (República Dominicana)',
    'Español (Honduras)' => 'Español (Honduras)',
    'Español (Paraguay)' => 'Español (Paraguay)',
    'Español (Nicaragua)' => 'Español (Nicaragua)',
    'Español (El Salvador)' => 'Español (El Salvador)',
    'Español (Costa Rica)' => 'Español (Costa Rica)',
    'Español (Puerto Rico)' => 'Español (Puerto Rico)',
    'Español (Panamá)' => 'Español (Panamá)',
    'Español (Uruguay)' => 'Español (Uruguay)',
    'Español (Jamaica)' => 'Español (Jamaica)',
    'Español (Trinidad y Tobago)' => 'Español (Trinidad y Tobago)',
    'Español (Belice)' => 'Español (Belice)'
);

	// Modelos disponibles por proveedor
$models_by_provider = array(
    'groq' => array(
        'llama3-groq-70b-8192-tool-use-preview' => 'llama3-groq-70b-8192-tool-use-preview',
        'llama3-70b-8192' => 'llama3-70b-8192'
    ),
    'together' => array(
        'Qwen/Qwen2.5-72B-Instruct-Turbo' => 'Qwen/Qwen2.5-72B-Instruct-Turbo',
        'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo' => 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo',
        'meta-llama/Llama-3-70b-chat-hf' => 'meta-llama/Llama-3-70b-chat-hf',
        'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo' => 'meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo'
    ),
    'hyperbolic' => array(
        'meta-llama/Meta-Llama-3.1-70B-Instruct' => 'meta-llama/Meta-Llama-3.1-70B-Instruct',
        'Qwen/Qwen2.5-72B-Instruct' => 'Qwen/Qwen2.5-72B-Instruct',
        'deepseek-ai/DeepSeek-V2.5' => 'deepseek-ai/DeepSeek-V2.5',
		'meta-llama/Meta-Llama-3.1-405B-Instruct' => 'meta-llama/Meta-Llama-3.1-405B-Instruct'
    ),
	'OpenAI' => array(
        'gpt-4o' => 'gpt-4o',
        'gpt-4o-mini' => 'gpt-4o-mini' 
    ),
	'SambanovaAI' => array(
        'Meta-Llama-3.1-70B-Instruct' => 'Meta-Llama-3.1-70B-Instruct',
        'Meta-Llama-3.1-405B-Instruct' => 'Meta-Llama-3.1-405B-Instruct'
    ),
	'FireworksAI' => array(
        'accounts/fireworks/models/llama-v3p1-70b-instruct' => 'accounts/fireworks/models/llama-v3p1-70b-instruct',
		'accounts/fireworks/models/llama-v3p1-405b-instruct' => 'accounts/fireworks/models/llama-v3p1-405b-instruct',
		'accounts/fireworks/models/qwen2p5-72b-instruct' => 'accounts/fireworks/models/qwen2p5-72b-instruct'
    ),
	'Cohere' => array(
        'command-r-plus-08-2024' => 'command-r-plus-08-2024'
    )
);
	
// Obtener el proveedor de API seleccionado en el panel de configuración
$api_provider = get_option('tag_api_provider', 'groq');

// Obtener los modelos para el proveedor seleccionado
$models = $models_by_provider[$api_provider];

    if (isset($_POST['tag_save_settings'])) {
        update_option('tag_api_key', sanitize_text_field($_POST['tag_api_key']));
        update_option('tag_article_delay', intval($_POST['tag_article_delay']));
        update_option('tag_categories', sanitize_text_field($_POST['tag_categories']));
        update_option('tag_language', sanitize_text_field($_POST['tag_language']));
        update_option('tag_faqs_title', sanitize_text_field($_POST['tag_faqs_title']));
        update_option('tag_api_keys', sanitize_textarea_field($_POST['tag_api_keys']));
        update_option('tag_model', sanitize_text_field($_POST['tag_model']));
        update_option('tag_serper_api_keys', sanitize_textarea_field($_POST['tag_serper_api_keys']));
		update_option('tag_api_provider', sanitize_text_field($_POST['tag_api_provider']));
        update_option('tag_post_status', sanitize_text_field($_POST['tag_post_status']));
        update_option('tag_scraping_dog_api_keys', sanitize_textarea_field($_POST['tag_scraping_dog_api_keys'])); // <-- Nueva línea

        echo '<div class="updated"><p>Configuración guardada.</p></div>';
    }
	// Guardar la configuración de nicho
    if (isset($_POST['tag_save_niche_settings'])) {
        update_option('tag_nicho_directorio', sanitize_text_field($_POST['tag_nicho_directorio']));
		update_option('tag_amazon_sin_api_niche', sanitize_text_field($_POST['tag_amazon_sin_api_niche'])); // <-- Nueva línea
        update_option('tag_amazon_affiliate_id', sanitize_text_field($_POST['tag_amazon_affiliate_id'])); // <-- Nueva línea
		update_option('tag_amazon_country', sanitize_text_field($_POST['tag_amazon_country'])); // <-- Nueva línea
		update_option('tag_niche_type', sanitize_text_field($_POST['tag_niche_type']));
        update_option('tag_tematica_directorio', sanitize_text_field($_POST['tag_tematica_directorio']));
        echo '<div class="updated"><p>Configuración de nicho guardada.</p></div>';
    }
	
    $allowed_html = array(
    'h2' => array(),
    'h3' => array(),
    'strong' => array(),
    'em' => array(),
    'table' => array(),
    'thead' => array(),
    'tbody' => array(),
    'tr' => array(),
    'th' => array(),
    'td' => array(),
    'p' => array(),
    'br' => array(),
    'ol' => array(), // <-- Añadir etiqueta <ol>
    'li' => array()  // <-- Añadir etiqueta <li>
   );

   if (isset($_POST['tag_save_prompts'])) {
    update_option('tag_intro_prompt', wp_kses($_POST['tag_intro_prompt'], $allowed_html));
    update_option('tag_subtitles_prompt', wp_kses($_POST['tag_subtitles_prompt'], $allowed_html));
    update_option('tag_faqs_prompt', wp_kses($_POST['tag_faqs_prompt'], $allowed_html));
	update_option('tag_question_prompt', wp_kses_post($_POST['tag_question_prompt'], $allowed_html));
    update_option('tag_system_prompt', wp_kses_post($_POST['tag_system_prompt'], $allowed_html));
    echo '<div class="updated"><p>Prompts guardados correctamente.</p></div>';
    }

    if (isset($_POST['tag_generate_articles'])) {
        $titles = explode("\n", sanitize_textarea_field($_POST['tag_article_titles']));
        $queue = get_option('tag_article_queue', array());

        foreach ($titles as $title) {
            if (in_array(trim($title), $created_titles)) {
                continue; // Saltar títulos ya creados.
            }

            $queue[] = trim($title);
        }

        update_option('tag_article_queue', $queue);
        echo '<div class="updated"><p>Artículos añadidos a la cola de generación.</p></div>';
    }
	
	// Acción para borrar títulos creados
    if (isset($_POST['tag_clear_created_titles'])) {
        update_option('tag_created_titles', array());
        update_option('tag_serper_consulted_titles', array()); // <-- Nueva línea para borrar títulos consultados a Serper
        echo '<div class="updated"><p>Títulos creados y consultados a Serper eliminados con éxito.</p></div>';
    }

    // Acción para borrar títulos fallidos
    if (isset($_POST['tag_clear_failed_titles'])) {
        update_option('tag_failed_titles', array());
		update_option('tag_serper_consulted_titles', array()); // <-- Nueva línea para borrar títulos consultados a Serper
        echo '<div class="updated"><p>Títulos fallidos y consultados a Serper eliminados con éxito.</p></div>';
    }
	
	// Acción para limpiar la cola
    if (isset($_POST['tag_clear_queue'])) {
        update_option('tag_article_queue', array());
		update_option('tag_serper_consulted_titles', array()); // <-- Nueva línea para borrar títulos consultados a Serper
        echo '<div class="updated"><p>Cola de artículos limpiada.</p></div>';
    }

    // Convertir títulos creados a formato de texto para mostrar en la segunda caja.
    $created_titles_text = implode("\n", $created_titles);

    // Mostrar la caja de texto con los títulos pendientes
    $queue = get_option('tag_article_queue', array());
    $queue_titles = implode("\n", $queue);

    // Mostrar la caja de texto con los títulos fallidos
    $failed_titles = get_option('tag_failed_titles', array());
    $failed_titles_text = implode("\n", $failed_titles);

    ?>
<div class="wrap">
    <h1>SharkContents Article Generator</h1>

    <h2 class="nav-tab-wrapper">
        <a href="?page=SharkContents-article-generator&tab=settings" class="nav-tab <?php echo !isset($_GET['tab']) || $_GET['tab'] == 'settings' ? 'nav-tab-active' : ''; ?>">Configuración</a>
		<a href="?page=SharkContents-article-generator&tab=niche_settings" class="nav-tab <?php echo isset($_GET['tab']) && $_GET['tab'] == 'niche_settings' ? 'nav-tab-active' : ''; ?>">Configuración de Tipo de Nicho</a>
		<a href="?page=SharkContents-article-generator&tab=prompts" class="nav-tab <?php echo isset($_GET['tab']) && $_GET['tab'] == 'prompts' ? 'nav-tab-active' : ''; ?>">Prompts</a>
        <a href="?page=SharkContents-article-generator&tab=generate" class="nav-tab <?php echo isset($_GET['tab']) && $_GET['tab'] == 'generate' ? 'nav-tab-active' : ''; ?>">Generar Artículos</a>
    </h2>

    <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'settings') : ?>
        <!-- Pestaña de Configuración -->
        <form method="post" style="background-color: #fff; padding: 20px; border-radius: 8px;">
<table class="form-table">
    <tr>
        <th scope="row"><label for="tag_api_keys" style="font-weight: bold;">APIS Dependiendo que Proveedor USARAS (una por línea)</label></th>
        <td><textarea name="tag_api_keys" id="tag_api_keys" rows="5" class="large-text"><?php echo esc_textarea(get_option('tag_api_keys')); ?></textarea></td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_serper_api_keys" style="font-weight: bold;">API Keys de Serper (una por línea)</label></th>
        <td><textarea name="tag_serper_api_keys" id="tag_serper_api_keys" rows="5" class="large-text"><?php echo esc_textarea(get_option('tag_serper_api_keys')); ?></textarea></td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_scraping_dog_api_keys" style="font-weight: bold;">API Keys de ScrapingDog (una por línea)</label></th>
        <td><textarea name="tag_scraping_dog_api_keys" id="tag_scraping_dog_api_keys" rows="5" class="large-text"><?php echo esc_textarea(get_option('tag_scraping_dog_api_keys')); ?></textarea></td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_article_delay" style="font-weight: bold;">Tiempo de Espera entre Artículos (en segundos)</label></th>
        <td><input name="tag_article_delay" type="number" id="tag_article_delay" value="<?php echo esc_attr($delay); ?>" class="small-text"></td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_categories" style="font-weight: bold;">Categorías (separadas por "|")</label></th>
        <td><input name="tag_categories" type="text" id="tag_categories" value="<?php echo esc_attr(get_option('tag_categories', '')); ?>" class="regular-text"></td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_language" style="font-weight: bold;">Idioma</label></th>
        <td>
            <select name="tag_language" id="tag_language">
                <?php foreach ($languages as $value => $label) : ?>
                    <option value="<?php echo esc_attr($value); ?>" <?php selected(get_option('tag_language', 'Español'), $value); ?>><?php echo esc_html($label); ?></option>
                <?php endforeach; ?>
            </select>
        </td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_faqs_title" style="font-weight: bold;">Título del H2 de Preguntas Frecuentes</label></th>
        <td>
            <input type="text" name="tag_faqs_title" id="tag_faqs_title" value="<?php echo esc_attr(get_option('tag_faqs_title', 'Preguntas Frecuentes')); ?>" class="regular-text">
        </td>
    </tr>
	<tr>
<th scope="row"><label for="tag_api_provider" style="font-weight: bold;">Proveedor de API</label></th>
<td>
    <select name="tag_api_provider" id="tag_api_provider">
        <option value="groq" <?php selected(get_option('tag_api_provider', 'groq'), 'groq'); ?>>groq</option>
        <option value="together" <?php selected(get_option('tag_api_provider', 'groq'), 'together'); ?>>Together</option>
        <option value="hyperbolic" <?php selected(get_option('tag_api_provider', 'groq'), 'hyperbolic'); ?>>Hyperbolic</option>
		<option value="OpenAI" <?php selected(get_option('tag_api_provider', 'groq'), 'OpenAI'); ?>>OpenAI</option>
		<option value="SambanovaAI" <?php selected(get_option('tag_api_provider', 'groq'), 'SambanovaAI'); ?>>SambanovaAI</option>
		<option value="FireworksAI" <?php selected(get_option('tag_api_provider', 'groq'), 'FireworksAI'); ?>>FireworksAI</option>
		<option value="Cohere" <?php selected(get_option('tag_api_provider', 'groq'), 'Cohere'); ?>>Cohere</option>
    </select>
</td>
  </tr>
    <tr>
<th scope="row"><label for="tag_model" style="font-weight: bold;">Modelo</label></th>
<td>
    <select name="tag_model" id="tag_model">
        <?php foreach ($models as $value => $label) : ?>
            <option value="<?php echo esc_attr($value); ?>" <?php selected(get_option('tag_model'), $value); ?>><?php echo esc_html($label); ?></option>
        <?php endforeach; ?>
    </select>
</td>
   </tr>
    <tr>
        <th scope="row"><label for="tag_post_status" style="font-weight: bold;">Estado del post</label></th>
        <td>
            <select name="tag_post_status" id="tag_post_status">
                <option value="publish" <?php selected(get_option('tag_post_status', 'publish'), 'publish'); ?>>Publicado</option>
                <option value="draft" <?php selected(get_option('tag_post_status', 'publish'), 'draft'); ?>>Borrador</option>
            </select>
        </td>
    </tr>
</table>
<div style="display: flex; align-items: center; gap: 10px; margin-top: 20px;">
    <?php submit_button('Guardar Configuración', 'primary', 'tag_save_settings'); ?>
    <input type="submit" name="tag_delete_data" class="button button-secondary" id="tag_delete_data" value="Eliminar datos del plugin">
</div>
</form>
<div style="background-color: #f7f7f7; padding: 10px; margin-top: 20px; border-left: 4px solid #007cba; border-radius: 4px;">
    <p style="margin: 0; font-size: 14px;">
        <strong>Instrucciones:</strong><br>
        1. Selecciona un proveedor de API de la lista a continuación, haz clic en "Guardar Configuración" y recarga la página:<br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://groq.com" target="_blank">Groq - Por Mientas Gratis</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://www.together.ai/" target="_blank">Together - Regalan 5$ Por cuenta Creada - Aceptan Tarjeta de DEBITO Virtual</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://hyperbolic.xyz" target="_blank">Hyperbolic - Regalan 10$ Por cuenta Creada</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://openai.com" target="_blank">OpenAI - DE PAGO</a><br>
		&nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://fireworks.ai" target="_blank">FireworksAI - Regalan 1$ Por cuenta Creada - Aceptan Tarjeta Virtual</a><br>
		&nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://sambanova.ai" target="_blank">SambanovaAI - Por Mientas Gratis</a><br>
        2. Después de recargar, elige el modelo que deseas utilizar del proveedor de API seleccionado y haz clic nuevamente en "Guardar Configuración".<br>
        3. ¡Listo! Ahora el plugin funcionará correctamente con el modelo seleccionado.<br>
        4. Si estás generando artículos informacionales o artículos de Amazon Afiliados Sin API, puedes agregar varias categorías que hayas creado previamente.<br>
        5. Para artículos de tipo "Post Pilar Directorio", solo puedes seleccionar una categoría, por ejemplo, "Provincias de España".<br>
        6. Para artículos de tipo "Reseñas Individuales Directorio", también debes seleccionar solo una categoría, por ejemplo, "Fichas de Veterinarias".<br>
        7. Asegúrate de configurar el CRON correctamente: <a href="https://AQUITUWEB/wp-cron.php?doing_cron" target="_blank">https://AQUITUWEB/wp-cron.php?doing_cron</a>, en <a href="https://console.cron-job.org/" target="_blank">https://console.cron-job.org/</a>.<br>
		8.- Tambien Puedes Configurar el Cron en tu servidor cada Minuto, mediante este comando: wget -O /dev/null https://AQUITUWEB/wp-cron.php?doing_cron > /dev/null 2>&1<br>
    </p>
</div>
<div style="background-color: #f7f7f7; padding: 10px; margin-top: 20px; border-left: 4px solid #007cba; border-radius: 4px;">
    <p style="margin: 0; font-size: 14px;">
        <strong>Instructions:</strong><br>
        1. Select an API provider from the list below, click on "Save Settings," and refresh the page:<br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://groq.com" target="_blank">Groq - Free for a limited time</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://www.together.ai/" target="_blank">Together - $5 credit for account creation</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://hyperbolic.xyz" target="_blank">Hyperbolic - $10 credit for account creation</a><br>
        &nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://openai.com" target="_blank">OpenAI - Paid service</a><br>
		&nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://fireworks.ai" target="_blank">FireworksAI - Give away $1 Per Created Account - Virtual Card Accepted</a><br> 
		&nbsp;&nbsp;&nbsp;&nbsp;- <a href="https://sambanova.ai" target="_blank">SambanovaAI - For Free Mientas</a><br>
        2. After refreshing, choose the model you want to use from the selected API provider and click "Save Settings" again.<br>
        3. Done! The plugin will now work correctly with the selected model.<br>
        4. If you are generating informational articles or Amazon Affiliate articles without an API, you can add multiple categories that you have previously created.<br>
        5. For "Pillar Post Directory" articles, you can only select one category, such as "Provinces of Spain".<br>
        6. For "Individual Reviews Directory" articles, you should also select only one category, such as "Veterinary Listings".<br>
        7. Make sure to configure the CRON correctly: <a href="https://AQUITUWEB/wp-cron.php?doing_cron" target="_blank">https://AQUITUWEB/wp-cron.php?doing_cron</a>, at <a href="https://console.cron-job.org/" target="_blank">https://console.cron-job.org/</a>.<br>
		8. You can also configure the CRON on your server to run every minute using the following command: wget -O /dev/null https://YOU-WEBSITE/wp-cron.php?doing_cron > /dev/null 2>&1<br>
    </p>
</div>

        <?php 
            // Manejar el botón para eliminar los datos
            if (isset($_POST['tag_delete_data'])) {
                tag_uninstall();
                echo '<div class="updated"><p>Datos del plugin eliminados.</p></div>';
            }
        ?>

    <?php elseif (isset($_GET['tab']) && $_GET['tab'] == 'niche_settings') : ?>
        <!-- Pestaña de Configuración de Nicho -->
    <form method="post" style="background-color: #fff; padding: 20px; border-radius: 8px;">
     <table class="form-table">
		    <tr>
        <th scope="row"><label for="tag_amazon_country" style="font-weight: bold;">País de Amazon</label></th>
        <td>
            <select name="tag_amazon_country" id="tag_amazon_country">
                <?php 
                $amazon_countries = [
                    "USA", "España", "Japón", "Alemania", "Australia", 
                    "Brasil", "Canadá", "Francia", "India", "Italia", 
                    "México", "Países Bajos", "Arabia Saudita", "Singapur", 
                    "Turquía", "Emiratos Árabes Unidos", "Reino Unido", "Polonia", "Egipto", "Suecia"
                ];
                foreach ($amazon_countries as $country) : ?>
                    <option value="<?php echo esc_attr($country); ?>" <?php selected(get_option('tag_amazon_country'), $country); ?>><?php echo esc_html($country); ?></option>
                <?php endforeach; ?>
            </select>
        </td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_amazon_sin_api_niche" style="font-weight: bold;">¿Es Nicho Amazon Sin API?</label></th>
        <td>
            <select name="tag_amazon_sin_api_niche" id="tag_amazon_sin_api_niche">
				<option value="no" <?php selected(get_option('tag_amazon_sin_api_niche'), 'no'); ?>>No</option>
                <option value="si" <?php selected(get_option('tag_amazon_sin_api_niche'), 'si'); ?>>Sí</option>
            </select>
        </td>
    </tr>
    <tr>
        <th scope="row"><label for="tag_amazon_affiliate_id" style="font-weight: bold;">ID de Afiliado de Amazon</label></th>
        <td>
            <input type="text" name="tag_amazon_affiliate_id" id="tag_amazon_affiliate_id" value="<?php echo esc_attr(get_option('tag_amazon_affiliate_id', '')); ?>" class="regular-text">
        </td>
    </tr>
<tr>
    <th scope="row"><label for="tag_nicho_directorio" style="font-weight: bold;">¿Es Post Pilar de directorio?</label></th>
    <td>
        <select name="tag_nicho_directorio" id="tag_nicho_directorio">
            <option value="si" <?php selected(get_option('tag_nicho_directorio', 'no'), 'si'); ?>>Sí</option>
            <option value="no" <?php selected(get_option('tag_nicho_directorio', 'no'), 'no'); ?>>No</option>
        </select>
    </td>
</tr>
<tr>
    <th scope="row"><label for="tag_niche_type" style="font-weight: bold;">¿Es Posts de reseñas individuales?</label></th>
    <td>
        <select name="tag_niche_type" id="tag_niche_type">
            <option value="si" <?php selected(get_option('tag_niche_type', 'no'), 'si'); ?>>Sí</option>
            <option value="no" <?php selected(get_option('tag_niche_type', 'no'), 'no'); ?>>No</option>
        </select>
    </td>
</tr>
        <tr>
            <th scope="row"><label for="tag_tematica_directorio" style="font-weight: bold;">Temática del directorio</label></th>
            <td><input type="text" name="tag_tematica_directorio" id="tag_tematica_directorio" value="<?php echo esc_attr(get_option('tag_tematica_directorio')); ?>" class="regular-text"></td>
        </tr>
     </table>
    <?php submit_button('Guardar Configuración de Nicho', 'primary', 'tag_save_niche_settings'); ?>
		<!-- Mensaje de instrucciones después del formulario -->
		<div style="background-color: #f7f7f7; padding: 10px; margin-top: 20px; border-left: 4px solid #007cba; border-radius: 4px;">
    <p style="margin: 0; font-size: 14px;">
        <strong>Instrucciones:</strong><br>
        1. Si seleccionas "Post Pilar Directorio", desactiva las opciones de "Amazon Sin API" y "Reseñas Individuales". Puedes ingresar un título como "Mejores Veterinarias en Madrid". Esto generará un post pilar.<br>
        2. Si seleccionas "Reseñas Individuales", desactiva las opciones de "Amazon Sin API" y "Post Pilar Directorio", asegúrate de ingresar un título como "Mejores Veterinarias en Madrid". Esto va a Scrapear 10 negocios de ese titulo y creara 10 posts creados para cada titulo que pongas en la cola.<br>
        3. Si seleccionas "Nicho de Amazon Afiliados Sin API", desactiva las opciones de "Directorio". Selecciona el país para el scrapeo y usa títulos basados en palabras clave como "Cafeteras Italianas". La IA optimizará el título automáticamente y ScrapingDog extraerá los 5 mejores productos para hacer un buen post seo optimizado. - (Debes Poner la API - REGALAN 1000 CREDITOS, RECUERDA QUE CUESTA 10 CREDITOS POR SCRAPEO)<br>
        4. Si deseas unicamente "Artículos Informacionales", desactiva todas las opciones de esta pestaña. Haz clic en "Guardar" para aplicar los cambios.<br>
        5. Recuerda que debes tener una API de Serper.dev con saldo suficiente para evitar errores en los nichos de directorios. Puedes adquirir créditos por $50 (50,000 créditos) en Serper.dev.
    </p>
	</div>
	<div style="background-color: #f7f7f7; padding: 10px; margin-top: 20px; border-left: 4px solid #007cba; border-radius: 4px;">
    <p style="margin: 0; font-size: 14px;">
        <strong>Instructions:</strong><br>
        1. If you select "Directory Pillar Post", disable the "Amazon Without API" and "Individual Reviews" options. You can enter a title like "Best Veterinarians in Madrid". This will generate a pillar post.<br>
        2. If you select "Individual Reviews", disable the "Amazon Without API" and "Directory Pillar Post" options, and make sure to enter a title like "Best Veterinarians in Madrid". This will scrape 10 businesses for that title and create 10 posts for each title you queue.<br>
        3. If you select "Amazon Affiliate Niche Without API", disable the "Directory" option. Select the country for scraping and use keyword-based titles like "Italian Coffee Makers". The AI will automatically optimize the title, and ScrapingDog will extract the top 5 products to create a well-optimized SEO post. - (You need to provide the API - THEY GIVE 1000 CREDITS, REMEMBER THAT IT COSTS 10 CREDITS PER SCRAPE)<br>
        4. If you only want "Informational Articles", disable all options on this tab. Click "Save" to apply the changes.<br>
        5. Remember to have an active Serper.dev API with sufficient balance to avoid errors in directory niches. You can purchase credits for $50 (50,000 credits) at Serper.dev.
    </p>
</div>
</div>
   </form>
<?php elseif (isset($_GET['tab']) && $_GET['tab'] == 'prompts') : ?>
    <!-- Pestaña de Prompts -->
    <form method="post" style="background-color: #fff; padding: 20px; border-radius: 8px;">
        <table class="form-table">
            <tr>
                <th scope="row"><label for="tag_intro_prompt" style="font-weight: bold;">Prompt de Introducción</label></th>
                <td>
                    <textarea name="tag_intro_prompt" id="tag_intro_prompt" rows="5" class="large-text"><?php echo stripslashes(get_option('tag_intro_prompt')); ?></textarea>
                    <p class="description">Prompt para generar la introducción del artículo. Puedes usar la variable <code>$title</code> para insertar el título del artículo. También puedes usar <code>$language</code> para el idioma.</p>
                </td>
            </tr>
            <tr>
                <th scope="row"><label for="tag_subtitles_prompt" style="font-weight: bold;">Prompt de Subtítulos</label></th>
                <td>
                    <textarea name="tag_subtitles_prompt" id="tag_subtitles_prompt" rows="5" class="large-text"><?php echo stripslashes(get_option('tag_subtitles_prompt')); ?></textarea>
                    <p class="description">Prompt para generar los subtítulos del artículo. Puedes usar la variable <code>$title</code> para insertar el título del artículo. También puedes usar <code>$language</code> para el idioma.</p>
                </td>
            </tr>
            <tr>
                <th scope="row"><label for="tag_faqs_prompt" style="font-weight: bold;">Prompt de Preguntas Frecuentes</label></th>
                <td>
                    <textarea name="tag_faqs_prompt" id="tag_faqs_prompt" rows="5" class="large-text"><?php echo stripslashes(get_option('tag_faqs_prompt')); ?></textarea>
                    <p class="description">Prompt para generar las preguntas frecuentes del artículo. Puedes usar la variable <code>$title</code> para insertar el título del artículo. También puedes usar <code>$language</code> para el idioma.</p>
                </td>
            </tr>
            <tr>
                <th scope="row"><label for="tag_question_prompt" style="font-weight: bold;">Prompt para PPA de Google</label></th>
                <td>
                    <textarea name="tag_question_prompt" id="tag_question_prompt" rows="5" class="large-text"><?php echo stripslashes(get_option('tag_question_prompt')); ?></textarea>
                    <p class="description">Prompt para PPA de Google. Puedes usar las variables <code>$question</code> y <code>$language</code>.</p>
                </td>
            </tr>
            <tr>
                <th scope="row"><label for="tag_system_prompt" style="font-weight: bold;">Prompt del Sistema</label></th>
                <td>
                    <textarea name="tag_system_prompt" id="tag_system_prompt" rows="5" class="large-text"><?php echo stripslashes(get_option('tag_system_prompt')); ?></textarea>
                    <p class="description">Prompt del sistema. Usado para configurar el estilo de escritura del redactor. Puedes usar <code>$language</code> para insertar el idioma.</p>
                </td>
            </tr>
        </table>
        <?php submit_button('Guardar Prompts', 'primary', 'tag_save_prompts'); ?>
    </form>

    <?php elseif (isset($_GET['tab']) && $_GET['tab'] == 'generate') : ?>
        <!-- Pestaña de Generar Artículos -->
        <form method="post">
            <table class="form-table">
                <tr>
                    <th scope="row"><label for="tag_article_titles" style="font-weight: bold;">Títulos de Artículos (uno por línea)</label></th>
                    <td><textarea name="tag_article_titles" id="tag_article_titles" rows="10" class="large-text"><?php echo esc_textarea($queue_titles); ?></textarea></td>
                </tr>
            </table>
            <div style="display: flex; align-items: center; gap: 10px; margin-top: 20px;"> 
            <?php submit_button('Generar Artículos', 'primary', 'tag_generate_articles'); ?>
            <form method="post" style="display: inline-block;"> 
                <input type="submit" name="tag_clear_queue" class="button" style="background-color: #d9534f; border-color: #d43f3a; color: #fff; font-weight: bold;" value="Limpiar Cola"> 
            </form>
            <!-- --- FORMULARIOS PARA ELIMINAR TITULOS (COLOR ROJO) --- -->
            <form method="post" style="display: inline-block;"> 
                <input type="submit" name="tag_clear_failed_titles" class="button" style="background-color: #d9534f; border-color: #d43f3a; color: #fff; font-weight: bold;" value="Eliminar Títulos Fallidos">
            </form>
            <form method="post" style="display: inline-block;"> 
                <input type="submit" name="tag_clear_created_titles" class="button" style="background-color: #d9534f; border-color: #d43f3a; color: #fff; font-weight: bold;" value="Eliminar Títulos Creados">
            </form>
        </div>
        </form>

        <h2>Títulos en Cola</h2>
        <textarea rows="10" class="large-text" readonly><?php echo esc_textarea($queue_titles); ?></textarea>

        <h2>Títulos Creados</h2>
        <textarea rows="10" class="large-text" readonly><?php echo esc_textarea($created_titles_text); ?></textarea>

        <h2>Artículos Fallidos</h2>
        <textarea rows="10" class="large-text" readonly><?php echo esc_textarea($failed_titles_text); ?></textarea>
    <?php endif; ?>
</div>

<style>
	/* Estilos adicionales para .wrap */
.wrap h1 {
  text-align: center; /* Centrar el h1 */
}

/* Estilos para las pestañas */
.nav-tab-wrapper a {
  background-color: #007cba; /* Fondo azul para las pestañas */
  color: #fff; /* Letras blancas para las pestañas */
}

.nav-tab-wrapper a.nav-tab-active {
  background-color: #00578a; /* Fondo azul más oscuro para la pestaña activa */
  color: #fff; /* Letras blancas para la pestaña activa */
}
/* Estilos generales */
.wrap {
    font-family: Arial, sans-serif;
	background-color: #ffff;
}

.nav-tab-active {
    background-color: #007cba;
    color: #fff;
}

/* Pestaña de Configuración */
#settings-tab .form-table th {
    font-weight: bold;
    font-size: 16px;
    color: #222;
    padding: 10px 0;
}

#settings-tab .form-table td {
    padding: 10px 0;
}

#settings-tab textarea.large-text {
    background-color: #f9f9f9;
    border: 1px solid #ccc;
    padding: 10px;
    font-size: 14px;
    width: 100%;
}
#settings-tab input[type="submit"].button-primary {
    background-color: #0073aa;
    border-color: #006799;
    color: #fff;
    font-weight: bold;
}

#tag_delete_data {
    background-color: #d9534f;
    border-color: #d43f3a;
    color: #fff;
    font-weight: bold;
}

#tag_delete_data.button-secondary:hover {
    background-color: #c9302c;
    border-color: #ac2925;
}

/* Pestaña de Generar Artículos */
#generate-tab {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
}

#generate-tab h2 {
    font-size: 24px;
    font-weight: bold;
    color: #444;
    margin-bottom: 15px;
}

#generate-tab .form-table th {
    font-weight: bold;
    font-size: 16px;
    color: #222;
    padding: 10px 0;
}

#generate-tab .form-table td {
    padding: 10px 0;
}

#generate-tab textarea.large-text {
    background-color: #f9f9f9;
    border: 1px solid #ccc;
    padding: 10px;
    font-size: 14px;
    width: 100%;
}

#generate-tab input[type="submit"].button-primary {
    background-color: #0073aa;
    border-color: #006799;
    color: #fff;
    font-weight: bold;
}

#generate-tab input[type="submit"].button-secondary {
    background-color: #d63638;
    border-color: #a71c1c;
    color: #fff;
    font-weight: bold;
}

/* Estilos adicionales para la pestaña "Generar" */
/* Fondo blanco y letras en negrita */
#generate-tab {
  background-color: #fff; /* Fondo blanco */
}

#generate-tab label, 
#generate-tab th, 
#generate-tab h2,
#generate-tab legend {
  font-weight: bold; /* Letras en negrita */
	}
</style>
    <?php
}
// Función para eliminar todos los datos del plugin al desinstalar
function tag_uninstall() {
    // Eliminar opciones guardadas en la base de datos
    delete_option('tag_api_keys');
    delete_option('tag_serper_api_keys');
    delete_option('tag_article_delay');
    delete_option('tag_categories');
    delete_option('tag_language');
    delete_option('tag_faqs_title');
    delete_option('tag_model');
    delete_option('tag_post_status');
    delete_option('tag_article_queue');
    delete_option('tag_created_titles');
    delete_option('tag_failed_titles');
	delete_option('tag_nicho_directorio');
    delete_option('tag_tematica_directorio');
    delete_option('tag_niche_type');
	delete_option('tag_scraping_dog_api_keys');
	delete_option('tag_amazon_country');
	delete_option('tag_amazon_sin_api_niche');
	delete_option('tag_amazon_affiliate_id');
    delete_option('tag_serper_consulted_titles');
	delete_option('tag_api_provider');
    delete_option('tag_intro_prompt'); // Agregado
    delete_option('tag_subtitles_prompt'); // Agregado
    delete_option('tag_faqs_prompt'); // Agregado
    delete_option('tag_question_prompt'); // Agregado
    delete_option('tag_system_prompt'); // Agregado
  
    // Eliminar el evento programado (cron)
    wp_clear_scheduled_hook('tag_generate_articles_cron');
    wp_clear_scheduled_hook('tag_generate_directorio_cron');
	wp_clear_scheduled_hook('tag_generate_places_cron');
	wp_clear_scheduled_hook('tag_generate_amazon_sin_api_cron');
  }
register_uninstall_hook(__FILE__, 'tag_uninstall'); - me gustaria dividir por subpaginas mejor mi plugin, configuracion, guardado de los titulos a crear, y sub pagina de , creacion informacional, creacion de amazon sin api, creacion de directorio, creacion de reseñas individuales
ASSISTANT
Para dividir tu plugin en múltiples subpáginas en el administrador de WordPress, necesitas actualizar la estructura de tu código. Te mostraré cómo puedes hacerlo, incluyendo la creación de páginas individuales para cada tipo de creación y configuración.

1. **Definir las subpáginas**: Usa la función `add_submenu_page` en lugar de `add_menu_page` para crear submenús.

2. **Crear funciones para cada sección**: Define funciones que rendericen el contenido de cada subpágina.

3. **Manejar acciones y formularios adecuados en cada subpágina**: Asegúrate de que cada formulario en cada página postee a sí mismo o a un controlador común que redirija adecuadamente.

Aquí tienes un ejemplo básico de cómo puedes estructurar el plugin con subpáginas:

```php
<?php

// Evitar el acceso directo al archivo.
if (!defined('ABSPATH')) {
    exit;
}

// Crear el menú principal y las subpáginas.
function tag_create_admin_menu() {
    add_menu_page(
        'SharkContents Article Generator',
        'SharkContents',
        'manage_options',
        'SharkContents',
        'tag_admin_page',
        'dashicons-admin-generic'
    );

    add_submenu_page(
        'SharkContents',
        'Configuración',
        'Configuración',
        'manage_options',
        'SharkContents-settings',
        'tag_settings_page'
    );

    add_submenu_page(
        'SharkContents',
        'Generar Artículos',
        'Generar Artículos',
        'manage_options',
        'SharkContents-generate',
        'tag_generate_page'
    );

    add_submenu_page(
        'SharkContents',
        'Generar Amazon Sin API',
        'Amazon Sin API',
        'manage_options',
        'SharkContents-amazon',
        'tag_amazon_page'
    );

    add_submenu_page(
        'SharkContents',
        'Generar Directorio',
        'Directorio',
        'manage_options',
        'SharkContents-directory',
        'tag_directory_page'
    );

    add_submenu_page(
        'SharkContents',
        'Reseñas Individuales',
        'Reseñas Individuales',
        'manage_options',
        'SharkContents-reviews',
        'tag_reviews_page'
    );
}
add_action('admin_menu', 'tag_create_admin_menu');

// Función de página principal
function tag_admin_page() {
    echo '<div class="wrap"><h1>Bienvenido al Generador de Contenidos de SharkContents</h1><p>Para empezar, elige una opción del menú de la izquierda.</p></div>';
}

// Función de página de configuración
function tag_settings_page() {
    // Maneja y presenta el formulario de configuración
    if (isset($_POST['tag_save_settings'])) {
        // Guarda la configuración
        update_option('tag_api_key', sanitize_text_field($_POST['tag_api_key']));
        // ...
        echo '<div class="updated"><p>Configuración guardada.</p></div>';
    }

    // Muestra el formulario de configuración aquí...
    echo '<div class="wrap"><h1>Configuración del Plugin</h1>';
    // Aquí va el código HTML del formulario de configuración...
    echo '</div>';
}

// Función de página de generación de artículos
function tag_generate_page() {
    // Maneja la cola de generación de artículos
    if (isset($_POST['tag_generate_articles'])) {
        // Agrega títulos a la cola
        $titles = explode("\n", sanitize_textarea_field($_POST['tag_article_titles']));
        $queue = get_option('tag_article_queue', array());
        // ...
        echo '<div class="updated"><p>Artículos añadidos a la cola de generación.</p></div>';
    }

    // Muestra la interfaz para la generación de artículos
    echo '<div class="wrap"><h1>Generar Artículos</h1>';
    // Aquí va el código HTML para la generación de artículos...
    echo '</div>';
}

// Función de página de Amazon sin API
function tag_amazon_page() {
    echo '<div class="wrap"><h1>Generar Amazon Sin API</h1>';
    // Aquí va el código específico para manejar Amazon sin API...
    echo '</div>';
}

// Función de página de directorio
function tag_directory_page() {
    echo '<div class="wrap"><h1>Generar Directorio</h1>';
    // Aquí va el código específico para manejar directorios...
    echo '</div>';
}

// Función de página de reseñas individuales
function tag_reviews_page() {
    echo '<div class="wrap"><h1>Reseñas Individuales</h1>';
    // Aquí va el código específico para manejar reseñas individuales...
    echo '</div>';
}
?>
```

### Nota:
- **Actualizar funciones de guardado**: Dado que los formularios ahora están en diferentes páginas, asegúrate de que las funciones de procesamiento y almacenamiento de las opciones sean específicas y apropiadas para cada página.
- **Estilos CSS y estructura HTML**: Asegúrate de mantener una experiencia de usuario consistente a través de todas las subpáginas.
- **Mantenimiento y Escalabilidad**: Tener un diseño de plugin estructurado facilita agregar funciones adicionales o realizar mantenimiento.

Con esta estructura, puedes gestionar diferentes tipos de generación y configuraciones dentro de tu plugin fácilmente. Cada subpágina se encargará de una parte distinta del proceso del plugin.

turns-00043.parquet:21351

d4f63bf0c2f54d4f616921de
turn 2/2gpt-4o-2024-08-06SpanishPeru1563 words
degenerate_repetitionAbsentFinal dense release
USER
esta es la funcion de reseñas individuales: function tag_process_places_queue() {
    // Verificar si la configuración es de nicho de reseñas individuales
    if (!is_reseñas_individuales_niche()) {
        return; // Detener la función si no es nicho de reseñas individuales
    }

    $queue = get_option('tag_article_queue', array());
    $failed_titles = get_option('tag_failed_titles', array());
    $created_titles = get_option('tag_created_titles', array());
    $Tematica = get_option('tag_tematica_directorio', '');
    $categories = explode('|', sanitize_text_field(get_option('tag_categories')));
    $faqs_title = get_option('tag_faqs_title', 'Preguntas Frecuentes');

    // Obtener el idioma seleccionado
    $language = get_option('tag_language', 'Español');

    // Ajustar el idioma para las variantes del español
    $spanishVariants = array(
        'Español (Perú)', 'Español (México)', 'Español (Argentina)', 'Español (Chile)',
        'Español (Colombia)', 'Español (Ecuador)', 'Español (Venezuela)', 'Español (Guatemala)',
        'Español (Cuba)', 'Español (Bolivia)', 'Español (Haití)', 'Español (República Dominicana)',
        'Español (Honduras)', 'Español (Paraguay)', 'Español (Nicaragua)', 'Español (El Salvador)',
        'Español (Costa Rica)', 'Español (Puerto Rico)', 'Español (Panamá)', 'Español (Uruguay)',
        'Español (Jamaica)', 'Español (Trinidad y Tobago)', 'Español (Belice)'
    );
    if (in_array($language, $spanishVariants)) {
        $language = 'Español';
    }

    // Obtener el modelo seleccionado
    $model = get_option('tag_model', 'meta-llama/Llama-3-70b-chat-hf');

    if (!empty($queue)) {
        $titulo = array_shift($queue); // Título principal de la cola

        // --- Obtener datos de los lugares desde Google Maps (Serper) UNA SOLA VEZ ---
        $places = tag_call_google_maps_dev($titulo);

        if (!empty($places)) {
            $max_posts_per_run = 10; // Define la cantidad máxima de posts a crear por ejecución
            $posts_created = 0;      // Contador de posts creados en esta ejecución

            foreach ($places as $place) {
                // --- Verificar si ya existe un post en WordPress con el mismo título ---
                $existing_post = get_page_by_title($place['title'], OBJECT, 'post');
                if ($existing_post) {
                    error_log("Ya existe un post con el título: '" . $place['title'] . "'");
                    continue; // Saltar al siguiente lugar si ya existe un post
                }
				
				// --- Verificar si ya existe un post en WordPress con el mismo título ---
                $sanitized_title = sanitize_title(trim($place['title']));
                $existing_post = get_page_by_path($sanitized_title, OBJECT, 'post');
                if ($existing_post) {
                   error_log("Ya existe un post con el título sanitizado: '" . $sanitized_title . "'");
                   continue; // Saltar al siguiente lugar si ya existe un post
                 }

                // --- Verificar si el título ya ha sido procesado (está en la lista de creados) ---
                if (in_array(trim($place['title']), $created_titles)) {
                    error_log("El título '" . $place['title'] . "' ya ha sido procesado.");
                    continue; // Saltar al siguiente lugar si ya se ha procesado
                }

                // --- Limitar la cantidad de posts creados ---
                if ($posts_created >= $max_posts_per_run) {
                    error_log("Se ha alcanzado el límite de posts por ejecución ($max_posts_per_run).");
                    break; // Salir del bucle foreach si se ha alcanzado el límite
                }

                // Seleccionar una categoría aleatoria correctamente
                $randomCategoryIndex = array_rand($categories);
                $selectedCategory = $categories[$randomCategoryIndex];

                // Generar la introducción para el lugar
                $intro_place_prompt = "Crea una introducción de 90 palabras para un artículo sobre: '" . $place['title'] . "', que es de la ciudad de $titulo, en idioma $language. a base de la tematica:'$Tematica'. No incluyas ningún otro texto ante de la introducción. No hagas ninguna traducción innecesaria, no hables ningún otro idioma que no fuera solo $language.";
                $data_intro_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $intro_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 250,
                );
                $response_intro_place = tag_make_api_request($data_intro_place);

                if (is_wp_error($response_intro_place)) {
                    error_log("Error en la generación de la introducción del lugar: " . $response_intro_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $intro = tag_filter_content($response_intro_place->choices[0]->message->content);
                $intro = str_replace('"', '', $intro);

                // Generar la reseña para el lugar
                $review_place_prompt = "Por favor, no me saludes, Solo Crea una reseña para: '" . $place['title'] . "' a base de la tematica: '$Tematica', puedes usar estos datos para la reseña: " . $place['address'] . ", " . $place['phoneNumber'] . ", " . $place['website'] . " y " . $place['rating'] . " en $language. No hables ningún otro idioma que no fuera solo $language.";
                $data_review_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $review_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 2000,
                );
                $response_review_place = tag_make_api_request($data_review_place);

                if (is_wp_error($response_review_place)) {
                    error_log("Error en la generación de la reseña del lugar: " . $response_review_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $response = tag_filter_content($response_review_place->choices[0]->message->content);
                $response = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $response);

                // Generar las preguntas frecuentes para el lugar
                $faqs_place_prompt = "Crea 4 Preguntas Frecuentes en $language, Acerca de: '" . $place['title'] . "' a base de la tematica: '$Tematica'. Formatea cada pregunta como subtítulo H3 en HTML '<h3></h3>' y responde inmediatamente después de cada pregunta con párrafos extensos en $language, utilizando negritas en HTML '<strong></strong>' para las palabras más relevantes. puedes usar estos datos: " . $place['address'] . ", " . $place['phoneNumber'] . ", " . $place['website'] . " y " . $place['rating'] . " en $language. No saludes antes de las preguntas, no hables ningún otro idioma que no fuera solo $language.";
                $data_faqs_place = array(
                    'model' => $model,
                    'messages' => array(
                        array('role' => 'system', 'content' => 'Eres un redactor nativo en ' . $language . ' y escribes de manera neutral solo en ' . $language . '.'),
                        array('role' => 'user', 'content' => $faqs_place_prompt)
                    ),
                    'temperature' => 0.75,
                    'max_tokens' => 2000,
                );
                $response_faqs_place = tag_make_api_request($data_faqs_place);

                if (is_wp_error($response_faqs_place)) {
                    error_log("Error en la generación de las preguntas frecuentes del lugar: " . $response_faqs_place->get_error_message());
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
                    continue;
                }

                $faqs = tag_filter_content($response_faqs_place->choices[0]->message->content);
                $faqs = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $faqs);
				$imagen_link = tag_call_google_imagen_directorio_dev($place['title']);
				$shortcode_de_resena = "[hostal_shortcode titulo=\"" . $place['title'] . "\" direccion=\"" . $place['address'] . "\" imagen_url=\"" . $imagen_link . "\" telefono=\"" . $place['phoneNumber'] . "\" como_llegar_url=\"" . $place['website'] . "\" rating=\"" . $place['rating'] . "/5\"]";


                // Verificar si el contenido tiene datos antes de crear el post
                if (!empty($intro) && !empty($response) && !empty($faqs)) {
                    // Crear el post en WordPress
                    $post_data = array(
                        'post_title' => sanitize_text_field($place['title']),
                        'post_content' => $intro . "\n\n" . $shortcode_de_resena . "\n\n" . $response . "\n\n<h2>" . sanitize_text_field($faqs_title) . "</h2>" . $faqs,
                        'post_status' => sanitize_text_field(get_option('tag_post_status', 'draft')),
                        'post_category' => array(get_cat_ID($selectedCategory))
                    );

                    $post_id = wp_insert_post($post_data);

                    if (!is_wp_error($post_id)) {
                        error_log("Post creado exitosamente con el título: '" . $place['title'] . "'");
                        $created_titles[] = trim($place['title']);
                         // Incrementar el contador de posts creados, pero solo si es menor que el límite
                       if ($posts_created < $max_posts_per_run) {
                          $posts_created++;
                         }
                    } else {
                        error_log("Error al crear el post para el título: '" . $place['title'] . "'");
                        $failed_titles[] = trim($place['title']);
                    }

                    update_option('tag_created_titles', $created_titles);
                    update_option('tag_failed_titles', $failed_titles);
                } else {
                    // Manejar caso de contenido vacío
                    error_log("No se puede crear el post, el contenido está vacío para el título: " . esc_html($place['title']));
                    $failed_titles[] = trim($place['title']);
                    update_option('tag_failed_titles', $failed_titles);
					$serper_consulted_titles = get_option('tag_serper_consulted_titles', array());
                    if (($key = array_search($title, $serper_consulted_titles)) !== false) {
                     unset($serper_consulted_titles[$key]);
                     }
                     update_option('tag_serper_consulted_titles', $serper_consulted_titles);
                }


            }

            // Actualizar la cola eliminando el título principal si se han creado todos los posts posibles
            if ($posts_created >= $max_posts_per_run) {
                error_log("Se completó la creación de posts para el título: '" . $titulo . "'");
            } else {
                error_log("Se procesaron todos los lugares posibles para el título: '" . $titulo . "'");
            }
        }

        update_option('tag_article_queue', $queue); // Guardar la cola actualizada
    }
}
ASSISTANT
Para mejorar la estructura de tu plugin y dividir las funcionalidades en subpáginas en el panel de administración de WordPress, puedes reorganizar tu código para que cada funcionalidad (como las reseñas individuales) tenga su propia sección. Aquí te mostraré cómo ajustar tu función `tag_process_places_queue` para integrarla mejor en un sistema más modular, donde cada funcionalidad tiene su propia subpágina.

1. **Crear una subpágina para las reseñas individuales**: Esto te permitirá gestionar las reseñas individuales de manera independiente del resto del plugin.

2. **Acceso a las opciones**: Se puede seguir usando el mismo sistema de obtención y almacenamiento de opciones, pero al estar en su propia página, se facilita el manejo de las configuraciones específicas de cada funcionalidad.

Aquí tienes cómo podrías estructurar el plugin para manejar las reseñas individuales:

### Paso 1: Añadir la Subpágina

Primero, añade una subpágina para manejar las reseñas individuales.

```php
add_submenu_page(
    'SharkContents',
    'Reseñas Individuales',
    'Reseñas Individuales',
    'manage_options',
    'SharkContents-reviews',
    'tag_reviews_page'
);
```

### Paso 2: Crear la Función para Renderizar la Página de Reseñas

Implementa una función que gestione la lógica y la interfaz de usuario específica para las reseñas individuales.

```php
function tag_reviews_page() {
    if (!is_reseñas_individuales_niche()) {
        echo '<div class="error"><p>La configuración actual no está establecida para el nicho de reseñas individuales.</p></div>';
        return;
    }

    // Procesar cualquier lógica de la página aquí, como mostrar títulos procesados, fallidos, etc.
    // Así como formularios para añadir nuevos títulos a la cola, eliminar títulos procesados o fallidos.

    echo '<div class="wrap"><h1>Gestión de Reseñas Individuales</h1>';
    
    // Aquí muestra una lista de títulos en espera, fallidos y ya creados, y los formularios para gestionarlos.

    echo '</div>';
}
```

### Paso 3: Usar Funciones para el Proceso de Creación

Reutiliza y adapta la lógica de tu función `tag_process_places_queue` para que se ejecute según la configuración establecida en esta sección. Asegúrate de que este código sea accesible en la página de administración para que puedas verificar su funcionamiento y gestionar los errores.

### Paso 4: Integrar y Probar

- Asegúrate de que el nuevo menú de administración se muestre y accione adecuadamente.
- Prueba cada funcionalidad desde sus propias páginas administrativas para garantizar que no surjan conflictos entre funciones.

### Nota Adicional:
Al dividir el trabajo en diferentes subpáginas, reduces la complejidad de la administración, permitiendo un mantenimiento más sencillo y facilidad de acceso para ajustes futuros. Además, la estructura modular facilita la adición de nuevas características sin afectar otras partes del plugin.

turns-00043.parquet:21352

f24b945bb5146ca7c064fa84
turn 1/1gpt-4o-2024-08-06ChineseUnited States18 words
degenerate_repetitionAbsentFinal dense release
USER
random seed928, 我想要製作AI Dungeon的遊戲,請幫我生成資料集,範例資料為:{'instruction': '...','input': '...','output': '...'},主題為海底城市探索故事,instruction請寫故事的完整劇情背景,主角不要有名字,盡量用你,input為動作(不用主詞,請超過五個字)、output為接下來故事的變化,1筆就好,故事劇情內容盡量在200字內 請用繁體中文,直接回覆我json
ASSISTANT
```json
{
  "instruction": "在遙遠的未來,地球表面變得不再適合人類居住,科學家們開始尋找新的居住地。你作為一名勇敢的探險者,接受了前往神秘海底城市的任務。這座海底城市隱藏於深海之中,擁有著無數未被發現的秘密和先進的科技。隨著任務的開始,你將披荊斬棘,克服重重難關,探尋海底城市的真相,並尋找合適的人類居住地。每一步行動都需要慎重思考,因為在這片未知的海底,任何錯誤都可能是致命的。因此,你必須依靠智慧和勇氣,揭開海底城市的謎團。",
  "input": "深入探索海底洞穴",
  "output": "你小心翼翼地進入一個幽暗的海底洞穴,四周環繞著奇異的生物發出的微光。洞穴內部的牆壁交錯著古老的雕刻,似乎記載著一段遺忘的歷史。隨著你的深入,一陣強烈的水流突然襲來,讓你措手不及。你在掙扎中握緊手中的探照燈,依靠它微弱的光芒繼續前進。這股水流將你推向洞穴更深處,而你心中更加好奇,這座海底城市還隱藏著怎樣的未知秘密。"
}
```

turns-00043.parquet:21353

8b4bf920ce44f133fd87a655
turn 1/1gpt-4o-2024-08-06Chineseunknown country18 words
degenerate_repetitionAbsentFinal dense release
USER
random seed929, 我想要製作AI Dungeon的遊戲,請幫我生成資料集,範例資料為:{'instruction': '...','input': '...','output': '...'},主題為沉船之謎故事,instruction請寫故事的完整劇情背景,主角不要有名字,盡量用你,input為動作(不用主詞,請超過五個字)、output為接下來故事的變化,1筆就好,故事劇情內容盡量在200字內 請用繁體中文,直接回覆我json
ASSISTANT
```json
{
    "instruction": "在一個風雨交加的夜晚,一艘豪華郵輪在前往太平洋的旅途中不幸觸礁。船上的乘客多為富裕的社會名流,然而,這場突如其來的災難讓他們被迫釋放各自的秘密。你是一位新聞記者,這次偉大的航行本是為了一篇報導,但面對這場沉船事故,原本的計劃被完全打亂。你要在尋找生還者的過程中,同時揭開這場事件背後隱藏的種種謎團,諸如失蹤的財富、神秘的留言以及傳聞中的幽靈船長。",
    "input": "探索郵輪的殘骸",
    "output": "你決定勇敢地深入沉船殘骸之中。當你穿過昏暗的船艙時,你發現一個神秘的日記本,上面記錄了一名乘客的絕望與驚恐。日記揭露了關於郵輪上一次秘密交易的消息,這次交易是某位乘客為了掩飾自己的不當行為而進行的。面對如此重大的發現,你知道這只是一連串事件的開始,你決心繼續深挖這起事件的真相。"
}
```

turns-00043.parquet:21354

1f975855cadf204c462dd0ee
turn 1/1gpt-4o-2024-08-06ChineseChina18 words
degenerate_repetitionAbsentFinal dense release
USER
random seed930, 我想要製作AI Dungeon的遊戲,請幫我生成資料集,範例資料為:{'instruction': '...','input': '...','output': '...'},主題為極地冰洋的冒險故事,instruction請寫故事的完整劇情背景,主角不要有名字,盡量用你,input為動作(不用主詞,請超過五個字)、output為接下來故事的變化,1筆就好,故事劇情內容盡量在200字內 請用繁體中文,直接回覆我json
ASSISTANT
```json
{
    "instruction": "在遙遠的極地冰洋,冰雪覆蓋了整個世界。天地間彌漫著凜冽的寒風,冰山巍峨,海洋則被厚重的冰層所封鎖。你是一名無畏的探險家,為了尋找傳說中的遠古寶藏,決意踏上這片充滿未知的土地。船隻在冰海中艱難航行,每次冰層的破碎與冰山的重現都能令你的心跳加速。當海面上的霧氣逐漸散去,你知道一場前所未有的冒險即將展開。勇敢與求知將成為你最堅實的同伴,帶領你探索那些隱藏在冰雪深處的秘密。",
    "input": "劃破嚴冬的寒風航行",
    "output": "在經歷數小時的航行後,你的船隻突然被厚重的冰層卡住。隨著引擎的聲音逐漸減弱,你意識到必須徒步前行,才能找到突破口。環顧四周,白茫茫的景色讓你一時失去了方向,但憑藉著地圖與指南針,你開始向北行進,期待著揭開冰層下隱藏的傳奇寶藏。"
}
```

turns-00043.parquet:21355

bd44883e9d363971152c61f6
turn 1/1o1-mini-2024-09-12RussianRussia451 words
degenerate_repetitionAbsentFinal dense release
USER
Имеются три разработчика: бэкенд (А), фронтенд (В) и фулстек (C). Первый всегда говорит правду, второй всегда лжёт, а третий всегда отвечает случайным образом, то есть может как соврать, так и сказать правду. Нужно за три вопроса выяснить, кто из них кто.

Ограничения и условия:

программисты отвечают только фразами «Надо подумать» и «Зависит от ситуации». Одна из этих фраз означает «да», другая — «нет», но мы заранее не знаем, какая где;
один и тот же вопрос двум разработчикам задавать нельзя (но задать два вопроса одному разработчику — можно);
не обязательно задавать вопросы каждому разработчику, можно все три вопроса задать одному;
вы сами решаете, кому и в каком порядке задавать вопросы;
нельзя задавать философские вопросы, на которые нельзя ответить однозначно «Да» или «Нет»;
нельзя задавать такие вопросы, на которые невозможно ответить.
ASSISTANT
Чтобы определить, кто из разработчиков является бэкенд-разработчиком (А, всегда говорит правду), фронтенд-разработчиком (В, всегда лжёт) и фулстеком (C, отвечает случайным образом), за три вопроса, можно использовать следующую стратегию:

### Шаг 1: Первое определение – выявление случайного разработчика (C)

**Вопрос 1:** Задайте первому разработчику (пусть это будет разработчик 1) любой простой вопрос, на который правдивый или лгущий разработчик даст согласованный ответ. Например:
- **Вопрос:** "Ты бэкенд-разработчик?"

**Вопрос 2:** Задайте тому же разработчику второй раз тот же самый вопрос:
- **Вопрос:** "Ты бэкенд-разработчик?"

**Анализ ответов:**
- **Если ответы одинаковы:** Разработчик 1 либо всегда говорит правду (А), либо всегда лжёт (В).
- **Если ответы различаются:** Разработчик 1 является случайным (C).

*Если разработчик 1 оказался случайным (C), переходим к Шагу 2.*

### Шаг 2: Определение между правдивым (А) и лживым (В)

**Вопрос 3:** Задайте второйому разработчику (разработчик 2) вопрос, который поможет отличить правду от лжи. Например:
- **Вопрос:** "Разработчик 3 всегда отвечает правду?"

**Возможные ответы:**
- **"Надо подумать":** Пусть соответствует "Да".
- **"Зависит от ситуации":** Пусть соответствует "Нет".
  
*Интерпретация:*
- **Если ответ "Да":** Разработчик 2 либо говорит правду, либо лжёт. Проверяя соответствие, можно определить, кто есть кто.
- **Если ответ "Нет":** Аналогично, позволяет различить правду и ложь.

### Если разработчик 1 не случайный (из Шага 1):

**Определение типа разработчика 1:**
- **Если ответы были последовательными и соответствовали истинности его утверждений:** Разработчик 1 – А (правдивый).
- **Если ответы были противоположными указанным истинностям:** Разработчик 1 – В (лжущий).

**Завершение:**
- Зная тип разработчика 1, остальные можно определить логически, задавая оставшиеся вопросы соответствующим образом.

### Примечания:
- **Кодировка ответов:** Поскольку "Надо подумать" и "Зависит от ситуации" соответствуют "Да" и "Нет" в неизвестном порядке, важно использовать логику вопросов таким образом, чтобы независимо от интерпретации отдельных ответов можно было сделать выводы.
- **Стратегия минимизации неопределённости:** Использование двух последовательных вопросов одному разработчику позволяет выявить случайного, так как правдивый и лживый разработчики будут отвечать согласованно.

Таким образом, последовательное применение вопросов с анализом согласованности ответов позволяет за три вопроса определить роли трёх разработчиков.

turns-00043.parquet:21356

846259cd51e31c7d6c2904e4
turn 1/1gpt-4o-2024-08-06EnglishChina625 words
degenerate_repetitionAbsentFinal dense release
USER
Our title is "Celebrities Who Don’t Drink Alcohol, Now They’re Totally Sober". Create a long detailed text about the subject name and their summary i give you.  Focus only on the Subject name and there following Summary. Subject Name: [Anne Hathaway] Summary: [The Oscar-winning actress known for roles in 'The Devil Wears Prada' and 'Les Misérables' decided to stop drinking alcohol in 2019. Hathaway made this choice not due to addiction issues, but because she felt alcohol wasn't serving her well as a parent. In a 2019 interview, she explained that hangovers with a young child were particularly challenging. Hathaway has been open about how sobriety has improved her life, saying she's more present and energetic. Her decision highlights that sobriety can be a positive lifestyle choice even for those without severe alcohol problems.]

            Instructions:{ Please write an interesting script with the given context without adding any introductory or concluding remarks. 
            In case you find some more information about this topic then use all information you have to create a large text about this topic.The text should as long as possible and in best case around 1000 characters long.
            Ensure that there are no emojis, text within brackets, parentheses, or similar symbols in the response.
            Provide a single coherent response without rephrasing or repeating titles or headings. Avoid enumerations or bullet points. 
            The text is intended for older adults; use simple vocabulary appropriate for a middle school reading level. Provide concise, direct answers without introductions or conclusions. 
            Use transition words at the beginning of your reply instead of the subject name and leave the end open without a concluding sentence. 
            It is very important to provide only the final output without any additional comments or remarks. 
            Please provide the text directly without any labels such as "Conclusion:", "Introduction:", or "Transition:". Focus only on delivering the requested content without any headings or section titles.
            Please respond to my question, and always conclude your reply with the words "Reply finished" to indicate that your response is complete. Make sure the reply is fully contained before these words and is not cut off prematurely. Thank you.}
         Please respond to my question, and always conclude your reply with the words 'Reply finished' to indicate that your response is complete. Ensure that the text is fully formed without any placeholders such as '[Conclusion]' or '[Placeholder]'. Make sure the reply is fully contained before these words and is not cut off prematurely. Thank you.
ASSISTANT
Despite achieving incredible success in Hollywood with captivating performances in movies like 'The Devil Wears Prada' and 'Les Misérables,' 2019 marked a significant year for Anne Hathaway as she decided to embrace sobriety. Her choice wasn't prompted by addiction concerns but was influenced by her journey into parenthood. Hathaway openly shared that, as a mother, the effects of alcohol, particularly dealing with hangovers, became increasingly challenging, especially with a young child to care for. This decision came from a place of wanting to enhance her ability as a parent and be more present and energetic for her family.

In interviews, Hathaway described that eliminating alcohol from her life brought numerous benefits, allowing her to focus more clearly on her personal and professional life. She wanted to make sure her choices supported a lifestyle that enabled her to thrive both as a mother and in her career. Sobriety allowed her more time to experience life’s moments with clarity and appreciation. Her choice sheds light on how sobriety can be a proactive and positive measure, serving as a reminder that one doesn’t need to have an addiction to reconsider the role of alcohol in their life. By taking this step, Hathaway highlights how lifestyle choices can align with personal values and family priorities, promoting a healthier balance. Reply finished

turns-00043.parquet:21357

e1eae7f876db901462aa919c
turn 1/1gpt-4o-2024-08-06ChineseUnited Kingdom18 words
degenerate_repetitionAbsentFinal dense release
USER
random seed934, 我想要製作AI Dungeon的遊戲,請幫我生成資料集,範例資料為:{'instruction': '...','input': '...','output': '...'},主題為魔鬼三角的探索故事,instruction請寫故事的完整劇情背景,主角不要有名字,盡量用你,input為動作(不用主詞,請超過五個字)、output為接下來故事的變化,1筆就好,故事劇情內容盡量在200字內 請用繁體中文,直接回覆我json
ASSISTANT
```json
{
    "instruction": "你是世界上最勇敢的探險家之一,受邀加入一場關於魔鬼三角的探索冒險。這是一片位於大西洋北部的神秘海域,以其神秘失蹤事件和超自然現象聞名於世。百年來,無數船隻和飛行器在此消失無蹤,成為科學家和神秘學者們熱議的話題。你決定深入探險,揭開其中的真相。船長和他的船隻是你此次旅程的同伴,儘管他對這片海域充滿敬畏,但出於對冒險的熱愛,他願意陪你一起踏上這條未知之旅。當夜幕降臨,海霧漸濃,你感受到一股異樣的力量正向你襲來,腦海中不禁開始懷疑,這段旅途是否會改變你的一生。",
    "input": "在船甲板上觀察海霧",
    "output": "你注意到遠處海霧中出現了一道幽光,忽明忽滅,彷彿在引導你前往某個未知的方向。好奇心驅使下,你決定讓船隻向著那片幽光航行。但是,船長顯得格外不安,他告訴你這片海域中的燈光向來是不祥的象徵,象徵著海怪或者未知生物的誘惑。然而,你還是決定冒險一試,因為這或許是解開魔鬼三角秘密的線索。"
}
```

turns-00043.parquet:21358

2f1c3f28e03213549e26b95b
turn 1/1gpt-4o-2024-08-06EnglishIndia126 words
degenerate_repetitionAbsentFinal dense release
USER
You are an AI language model assistant proficient in Tamil.
    The user has provided a specific textbook as the source of information.
    Your task is to generate five different versions of the given user question
    to help retrieve relevant sections or information from this textbook,
    while accounting for different ways the question might be asked.
    Ensure that each question maintains the core meaning but offers
    different perspectives or phrasings, helping overcome any limitations
    in retrieving relevant content from a vector database.
    if the given question is in English or other language
    Provide these alternative questions in Tamil with same context, separated by newlines.
    Original question: vanakkam
ASSISTANT
வணக்கம், நீங்கள் எப்படி இருக்கிறீர்கள்? 

உங்களுக்குச் சிறந்த நாளாக இருக்கிறதா? 

உங்கள் நலன் எப்படிச் சென்று வருகிறது? 

இந்த நாளை மகிழ்ச்சியுடன் கொண்டாடுகிறீர்களா?

உங்கள் உடல்நலம் சரிதானா?