PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.5.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.5.3
4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 All 200 releases
← All changes | includes/Core/WriteWithAI.php +853 -1105 4.5.53.5.3 View file →
@@ -1,115 +1,76 @@
1 1 <?php
2 2
3 - namespace WPDeveloper\BetterDocs\Core;
3 +namespace WPDeveloper\BetterDocs\Core;
4 4
5 -if ( ! defined( 'ABSPATH' ) ) {
6 - exit;
7 -}
5 +use WPDeveloper\BetterDocs\Utils\Base;
6 +use WPDeveloper\BetterDocs\Core\Settings;
7 +use WPDeveloper\BetterDocs\Core\PostType;
8 8
9 +use WPDeveloper\BetterDocs\Utils\Helper;
9 10
10 - use WPDeveloper\BetterDocs\Utils\Base;
11 - use WPDeveloper\BetterDocs\Core\Settings;
12 - use WPDeveloper\BetterDocs\Core\PostType;
13 -
14 - use WPDeveloper\BetterDocs\Utils\Helper;
15 - use WPDeveloper\BetterDocs\Utils\AIHelper;
16 -
17 - class WriteWithAI extends Base {
18 -
11 +class WriteWithAI extends Base
12 +{
19 13 public $settings;
20 14
21 - public function __construct( Settings $settings ) {
15 + public function __construct(Settings $settings)
16 + {
22 17 $this->settings = $settings;
23 18 // Get the post ID from the URL
24 - $post_id = isset( $_GET[ 'post' ] ) ? intval( $_GET[ 'post' ] ) : 0; // phpcs:ignore
19 + $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0;
25 20
26 - if ( ! empty( $_GET[ 'post_type' ] ) ) { // phpcs:ignore
27 - $post_type = $_GET[ 'post_type' ]; // phpcs:ignore
28 - } elseif ( $post_id > 0 ) {
29 - $post_type = get_post_type( $post_id );
21 + if (!empty($_GET['post_type'])) {
22 + $post_type = $_GET['post_type'];
23 + } else if ($post_id > 0) {
24 + $post_type = get_post_type($post_id);
30 25 } else {
31 26 $post_type = '';
32 27 }
33 28
34 - if ( ! empty( $this->isEnabledWriteWithAI() ) && 'docs' == $post_type ) {
35 - add_action( 'admin_footer', array( $this, 'ai_autowrite_button' ) );
36 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_ai_edit_assets' ) );
29 + if (!empty($this->isEnabledWriteWithAI()) && $post_type == 'docs') {
30 + add_action('admin_footer', [$this, 'ai_autowrite_button']);
37 31 }
38 - add_action( 'wp_ajax_generate_openai_content', array( $this, 'generate_openai_content_callback' ) );
32 + add_action('wp_ajax_generate_openai_content', [$this, 'generate_openai_content_callback']);
39 33 }
40 34
41 - public function enqueue_ai_edit_assets( $hook ) {
42 - if ( 'post.php' !== $hook && 'post-new.php' !== $hook ) {
43 - return;
44 - }
45 -
46 - global $post_type;
47 - if ( 'docs' !== $post_type ) {
48 - return;
49 - }
50 -
51 - if ( empty( $this->get_api_key() ) ) {
52 - return;
53 - }
54 -
55 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit', 'blocks/ai-edit.js' );
56 - betterdocs()->assets->enqueue( 'betterdocs-ai-edit-style', 'blocks/ai-edit-style.css' );
57 -
58 - wp_localize_script(
59 - 'betterdocs-ai-edit',
60 - 'betterdocsAIEdit',
61 - array(
62 - 'rest_url' => esc_url_raw( rest_url( 'betterdocs/v1/ai-edit' ) ),
63 - 'rest_nonce' => wp_create_nonce( 'wp_rest' ),
64 - 'post_id' => get_the_ID()
65 - )
66 - );
67 - }
68 -
69 - public function isEnabledWriteWithAI() {
70 - $isEnableAutoWrite = $this->settings->get( 'enable_write_with_ai', true );
35 + public function isEnabledWriteWithAI()
36 + {
37 + $isEnableAutoWrite = $this->settings->get('enable_write_with_ai', true);
71 38 return $isEnableAutoWrite;
72 39 }
73 40
74 - public function isValidAPIKey( $apiKey ) {
75 - if ( empty( $apiKey ) ) {
76 - $api_response[ 'valid' ] = false;
77 - $api_response[ 'message' ] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings#betterdocs-ai">OpenAI API Key</a> to use this Write with AI feature.';
41 + public function isValidAPIKey($apiKey)
42 + {
43 + if (empty($apiKey)) {
44 + $api_response['valid'] = false;
45 + $api_response['message'] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings">OpenAI API Key</a> to use this Write with AI feature.';
78 46
79 47 return $api_response;
80 48 }
81 49
82 - $api_response = array();
50 + $ch = curl_init('https://api.openai.com/v1/engines');
51 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
52 + curl_setopt($ch, CURLOPT_HTTPHEADER, [
53 + 'Content-Type: application/json',
54 + 'Authorization: Bearer ' . $apiKey,
55 + ]);
83 56
84 - $response = wp_safe_remote_get(
85 - 'https://api.openai.com/v1/engines',
86 - array(
87 - 'headers' => array(
88 - 'Content-Type' => 'application/json',
89 - 'Authorization' => 'Bearer ' . $apiKey,
90 - ),
91 - 'timeout' => 15,
92 - )
93 - );
57 + $api_response = [];
94 58
95 - if ( is_wp_error( $response ) ) {
96 - $api_response[ 'valid' ] = false;
97 - $api_response[ 'message' ] = $response->get_error_message();
98 - return $api_response;
99 - }
59 + $response = curl_exec($ch);
60 + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
100 61
101 - $httpCode = (int) wp_remote_retrieve_response_code( $response );
102 - $body = wp_remote_retrieve_body( $response );
62 + curl_close($ch);
103 63
104 - if ( 200 === $httpCode ) {
105 - $api_response[ 'valid' ] = true;
106 - $api_response[ 'message' ] = 'Valid API Key';
64 + if ($httpCode == 200) {
65 + $api_response['valid'] = true;
66 + $api_response['message'] = 'Valid API Key';
107 67 } else {
108 - $responseData = json_decode( $body, true );
109 - $messageData = ! empty( $responseData[ 'error' ] ) ? $responseData[ 'error' ] : array();
110 - $api_response[ 'valid' ] = false;
111 - $api_response[ 'message' ] = ! empty( $messageData[ 'message' ] ) ? $messageData[ 'message' ] : 'Invalid API Key';
68 + $responseData = json_decode($response, true);
69 + // Access the message data (replace 'data' with the actual key used in the response)
70 + $messageData = $responseData['error'] ? $responseData['error'] : '';
71 + $api_response['valid'] = false;
72 + $api_response['message'] = $messageData['message'] ? $messageData['message'] : 'Invalid API Key';
112 73 }
113 74
114 75 // print_r($response);
115 76
@@ -115,1238 +76,1025 @@
115 76
116 77 return $api_response;
117 78 }
118 79
119 - public function get_api_key() {
120 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
80 + public function get_api_key()
81 + {
82 + $api_key = $this->settings->get('ai_autowrite_api_key', '');
121 83 return $api_key;
122 84 }
123 85
124 - public function get_system_prompt() {
125 - $prompt = <<<'PROMPT'
126 -You are a Senior Technical Writer specializing in comprehensive, high-quality documentation. Your goal is to produce documentation that scores 100/100 on clarity, completeness, and structure.
127 86
128 -## Output format
129 -
130 -Return only HTML body content. Never wrap output in `<!doctype>`, `<html>`, `<head>`, `<body>`, or markdown code fences (no ```html ... ```).
131 -
132 -Use semantic, Gutenberg-friendly tags only:
133 -- Headings: `<h2>`, `<h3>`, `<h4>` (do not emit `<h1>` — it is reserved for the document title)
134 -- Paragraphs: `<p>` for prose
135 -- Lists: `<ul>`/`<ol>` with `<li>` for any list of items, steps, or bullet points — never fake a list with paragraphs or `<br>`
136 -- Links: `<a href="https://...">link text</a>` with absolute URLs
137 -- Inline emphasis: `<strong>`, `<em>`, `<code>`
138 -- Code blocks: `<pre><code>...</code></pre>` for multi-line code or commands
139 -- Quotes: `<blockquote>`
140 -- Tables: `<table>` with `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`
141 -- Images: `<img src="..." alt="...">`
142 -
143 -Apply `<span class="highlight">key term</span>` to important topic terms inside headings and to the first occurrence of each keyword in body text. Use it sparingly — never wrap whole sentences or wrap text inside `href`, `src`, `alt`, or other attributes.
144 -
145 -Do not emit `<style>`, `<script>`, `<iframe>`, `<form>`, or inline `style=""` / `class=""` attributes (other than the `highlight` class above).
146 -
147 -If — and only if — the user's prompt explicitly asks for raw/custom HTML, embed code, or a non-standard structure, follow that request instead of these defaults.
148 -PROMPT;
149 -
150 - return apply_filters( 'betterdocs_write_with_ai_system_prompt', $prompt );
151 - }
152 -
153 - public function generate_openai_response( $prompt, $keywords ) {
87 + public function generate_openai_response($prompt, $keywords)
88 + {
154 89 try {
155 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
156 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 2500 );
157 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
90 + $api_key = $this->settings->get('ai_autowrite_api_key', '');
91 + $max_tokens = $this->settings->get('ai_autowrite_max_token', 1500);
158 92
159 93 $api_endpoint = 'https://api.openai.com/v1/chat/completions'; // Update the endpoint based on OpenAI API version
160 94
161 - $request_body = AIHelper::build_openai_payload(
162 - $model,
163 - array(
164 - array(
165 - 'role' => 'system',
166 - 'content' => $this->get_system_prompt()
167 - ),
168 - array(
169 - 'role' => 'user',
170 - 'content' => $prompt
171 - )
172 - ),
173 - $max_tokens,
174 - null,
175 - 'write_with_ai'
176 - );
177 -
178 95 $request_options = array(
179 96 'headers' => array(
180 97 'Content-Type' => 'application/json',
181 - 'Authorization' => 'Bearer ' . $api_key
98 + 'Authorization' => 'Bearer ' . $api_key,
182 99 ),
183 - 'body' => json_encode( $request_body ),
184 - 'timeout' => 300
100 + 'body' => json_encode(array(
101 + 'model' => 'gpt-3.5-turbo', // Add the model parameter here
102 + 'messages' => array(
103 + array('role' => 'system', 'content' => 'You are a helpful assistant who writes documentation for users.'),
104 + array('role' => 'user', 'content' => $prompt),
105 + ),
106 + 'max_tokens' => $max_tokens,
107 +
108 + )),
109 + 'timeout' => 50,
185 110 );
186 111
187 - // GPT-5.5 reasoning can run well past the default limits; give PHP and
188 - // the HTTP call room to finish (still subject to server php-fpm/nginx limits).
189 - if ( function_exists( 'set_time_limit' ) ) {
190 - set_time_limit( 300 ); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- long-running AI generation needs an extended limit; still bounded by server fpm/nginx timeouts.
191 - }
112 + $response = wp_remote_post($api_endpoint, $request_options);
192 113
193 - $response = wp_remote_post( $api_endpoint, $request_options );
194 -
195 - if ( is_wp_error( $response ) ) {
114 + if (is_wp_error($response)) {
196 115 return 'Error: ' . $response->get_error_message();
197 116 } else {
198 - $body = wp_remote_retrieve_body( $response );
117 + $body = wp_remote_retrieve_body($response);
199 118
200 - $data = json_decode( $body, true );
119 + $data = json_decode($body, true);
201 120
202 - if ( ! empty( $data[ 'error' ] ) ) {
203 - return $data[ 'error' ][ 'message' ];
121 + if (!empty($data['error'])) {
122 + return $data['error']['message'];
204 123 }
205 124
206 - return $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ]; // Update this line to get the assistant's message
125 + return $data['choices'][0]['message']['content']; // Update this line to get the assistant's message
207 126 }
208 - } catch ( Exception $error ) {
127 + } catch (Exception $error) {
209 128 return 'Error: ' . $error->getMessage();
210 129 }
211 130 }
212 131
213 - public function generate_openai_response_ai_edit( $prompt ) {
214 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
215 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 2500 );
216 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
217 132
218 - $api_endpoint = 'https://api.openai.com/v1/chat/completions';
219 133
220 - $payload = AIHelper::build_openai_payload(
221 - $model,
222 - array(
223 - array(
224 - 'role' => 'system',
225 - 'content' => $this->get_system_prompt()
226 - ),
227 - array(
228 - 'role' => 'user',
229 - 'content' => $prompt
230 - )
231 - ),
232 - $max_tokens,
233 - null,
234 - 'write_with_ai'
235 - );
236 -
237 - $request_options = array(
238 - 'headers' => array(
239 - 'Content-Type' => 'application/json',
240 - 'Authorization' => 'Bearer ' . $api_key
241 - ),
242 - 'body' => wp_json_encode( $payload ),
243 - 'timeout' => 300
244 - );
245 -
246 - // GPT-5.5 reasoning can run well past the default limits; give PHP and
247 - // the HTTP call room to finish (still subject to server php-fpm/nginx limits).
248 - if ( function_exists( 'set_time_limit' ) ) {
249 - set_time_limit( 300 ); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- long-running AI generation needs an extended limit; still bounded by server fpm/nginx timeouts.
250 - }
251 -
252 - $response = wp_remote_post( $api_endpoint, $request_options );
253 -
254 - if ( is_wp_error( $response ) ) {
255 - return array(
256 - 'success' => false,
257 - 'error' => $response->get_error_message(),
258 - 'model' => $model
259 - );
260 - }
261 -
262 - $body = wp_remote_retrieve_body( $response );
263 - $data = json_decode( $body, true );
264 -
265 - if ( ! empty( $data[ 'error' ] ) ) {
266 - return array(
267 - 'success' => false,
268 - 'error' => isset( $data[ 'error' ][ 'message' ] ) ? $data[ 'error' ][ 'message' ] : 'OpenAI error',
269 - 'model' => $model,
270 - 'raw' => $data
271 - );
272 - }
273 -
274 - $content = isset( $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] ) ? $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ] : '';
275 - $usage = isset( $data[ 'usage' ] ) && is_array( $data[ 'usage' ] ) ? $data[ 'usage' ] : array();
276 -
277 - return array(
278 - 'success' => true,
279 - 'content' => $content,
280 - 'model' => $model,
281 - 'prompt_tokens' => isset( $usage[ 'prompt_tokens' ] ) ? (int) $usage[ 'prompt_tokens' ] : null,
282 - 'completion_tokens' => isset( $usage[ 'completion_tokens' ] ) ? (int) $usage[ 'completion_tokens' ] : null,
283 - 'total_tokens' => isset( $usage[ 'total_tokens' ] ) ? (int) $usage[ 'total_tokens' ] : null,
284 - 'finish_reason' => isset( $data[ 'choices' ][ 0 ][ 'finish_reason' ] ) ? $data[ 'choices' ][ 0 ][ 'finish_reason' ] : null
285 - );
286 - }
287 -
288 - public function generate_openai_content_callback() {
134 + public function generate_openai_content_callback()
135 + {
289 136 // Verify the nonce
290 - $ai_nonce = isset( $_POST['ai_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['ai_nonce'] ) ) : '';
291 - if ( ! wp_verify_nonce( $ai_nonce, 'generate_openai_content_nonce' ) ) {
292 - wp_send_json_error( 'Invalid nonce' );
137 + if (!isset($_POST['ai_nonce']) || !wp_verify_nonce($_POST['ai_nonce'], 'generate_openai_content_nonce')) {
138 + wp_send_json_error('Invalid nonce');
293 139 wp_die();
294 140 }
295 141
296 - if ( ! current_user_can( 'edit_posts' ) ) {
297 - wp_send_json_error( 'Insufficient permissions' );
298 - wp_die();
299 - }
142 + $prompt = sanitize_text_field($_POST['prompt']);
143 + // $num_of_sections = sanitize_text_field($_POST['numOfSections']);
144 + // $num_of_paragraphs = sanitize_text_field($_POST['numOfParagraphs']);
145 + $keywords = sanitize_text_field($_POST['keywords']);
300 146
301 - $prompt = isset( $_POST['prompt'] ) ? sanitize_text_field( wp_unslash( $_POST['prompt'] ) ) : '';
302 - $keywords = isset( $_POST['keywords'] ) ? sanitize_text_field( wp_unslash( $_POST['keywords'] ) ) : '';
147 + $ai_instance = new WriteWithAI($this->settings);
303 148
304 - $ai_instance = new WriteWithAI( $this->settings );
149 + $generated_content = $ai_instance->generate_openai_response($prompt, $keywords);
305 150
306 - $generated_content = $ai_instance->generate_openai_response( $prompt, $keywords );
307 -
308 151 // Send the generated content as the AJAX response
309 - wp_send_json_success( $generated_content );
152 + wp_send_json_success($generated_content);
310 153 wp_die();
311 154 }
312 155
313 - public function ai_autowrite_button() {
156 + public function ai_autowrite_button()
157 + {
314 158
315 159 ?>
316 - <script>
317 - var docsTitle;
160 + <script>
161 + var docsTitle;
318 162
319 - function responseMessage(message) {
320 - return `<div class="warning-message">
321 - <span class="dashicons dashicons-warning"></span>
322 - <div class="footer-message">
323 - ${message}
324 - </div>
325 - </div>`;
326 - }
163 + function responseMessage(message) {
164 + return `<div class="warning-message">
165 + <span class="dashicons dashicons-warning"></span>
166 + <div class="footer-message">
167 + ${message}
168 + </div>
169 + </div>`;
170 + }
327 171
328 - function generateArticle(e) {
172 + function generateArticle(e) {
329 173
330 174
331 - const title = document.getElementById('betterdocs-ai-title').value;
332 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
333 - // const sectionOptions = document.getElementById('bd-autowrtite-content-section');
334 - // const numOfSections = sectionOptions.options[sectionOptions.selectedIndex].value;
175 + const title = document.getElementById('betterdocs-ai-title').value;
176 + const keywords = document.getElementById('betterdocs-ai-keyword').value;
177 + // const sectionOptions = document.getElementById('bd-autowrtite-content-section');
178 + // const numOfSections = sectionOptions.options[sectionOptions.selectedIndex].value;
335 179
336 - // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
337 - // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
180 + // const paragraphOptions = document.getElementById('bd-autowrtite-content-paragraph');
181 + // const numOfParagraphs = paragraphOptions.options[paragraphOptions.selectedIndex].value;
338 182
339 - const contentTextArea = document.getElementById('betterdocs-ai-content');
340 - const docGenerateBtnTxt = document.querySelector('.generate-btn span');
183 + const contentTextArea = document.getElementById('betterdocs-ai-content');
184 + const docGenerateBtnTxt = document.querySelector('.generate-btn span');
341 185
342 - // Add nonce value to the data being sent
343 - const nonce = document.querySelector('input[name="ai_nonce"]').value;
344 - const isOverwrite = document.getElementById('betterdocs-ai-checkbox').checked;
345 - const generateDocLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
346 - const reGenerateDocLabel = "<?php echo esc_html__( 'Regenerate Doc', 'betterdocs' ); ?>";
186 + // Add nonce value to the data being sent
187 + const nonce = document.querySelector('input[name="ai_nonce"]').value;
188 + const isOverwrite = document.getElementById('betterdocs-ai-checkbox').checked;
189 + const generateDocLabel = "<?php echo esc_html__('Generate Doc', 'betterdocs'); ?>";
190 + const reGenerateDocLabel = "<?php echo esc_html__('Regenerate Doc', 'betterdocs'); ?>";
347 191
348 192
349 - // contentTextArea.value = `Write an article about ${title} in English. The article is organized by the following exact ${numOfSections} headings. Write exact ${numOfParagraphs} number of paragraphs per heading.${keywords} Use Markdown for formatting. Add an introduction and a conclusion. Style: creative. Tone: cheerful.`;
193 + // contentTextArea.value = `Write an article about ${title} in English. The article is organized by the following exact ${numOfSections} headings. Write exact ${numOfParagraphs} number of paragraphs per heading.${keywords} Use Markdown for formatting. Add an introduction and a conclusion. Style: creative. Tone: cheerful.`;
350 194
351 195
352 - // Check if the title is not empty
353 - if (title.trim() !== '' && keywords.trim() !== '') {
354 - e.preventDefault();
196 + // Check if the title is not empty
197 + if (title.trim() !== '' && keywords.trim() !== '') {
198 + e.preventDefault();
355 199
356 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
357 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
358 - }
200 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
201 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
202 + }
359 203
360 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generating...', 'betterdocs' ); ?>";
361 - jQuery('.generate-btn').prop('disabled', true);
204 + docGenerateBtnTxt.innerHTML = "<?php echo esc_html__('Generating...', 'betterdocs'); ?>";
205 + jQuery('.generate-btn').prop('disabled', true);
362 206
363 - jQuery.post({
364 - url: ajaxurl, // Make sure ajaxurl is defined in your script
365 - type: 'POST',
366 - data: {
367 - action: 'generate_openai_content',
368 - prompt: document.querySelector('#betterdocs-ai-content').value,
369 - // numOfSections: numOfSections,
370 - // numOfParagraphs: numOfParagraphs,
371 - keywords: keywords,
372 - ai_nonce: nonce, // Pass the nonce value
373 - },
374 - success: function(response) {
375 - // Update the content in the textarea
207 + jQuery.post({
208 + url: ajaxurl, // Make sure ajaxurl is defined in your script
209 + type: 'POST',
210 + data: {
211 + action: 'generate_openai_content',
212 + prompt: document.querySelector('#betterdocs-ai-content').value,
213 + // numOfSections: numOfSections,
214 + // numOfParagraphs: numOfParagraphs,
215 + keywords: keywords,
216 + ai_nonce: nonce, // Pass the nonce value
217 + },
218 + success: function(response) {
219 + // Update the content in the textarea
376 220
377 - if (response.success && (typeof response.data === 'string')) {
378 - docGenerateBtnTxt.innerHTML = "<?php echo esc_html__( 'Generated', 'betterdocs' ); ?>";
379 - setTimeout(() => {
380 - insertContentToEditor(title, response.data, isOverwrite, keywords);
381 - docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
382 - jQuery('.generate-btn').removeAttr('disabled');
383 - }, 2000);
384 - } else {
385 - // alert(response.data.message);
386 - jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
387 - jQuery('#betterdocs-ai-error-message').html(responseMessage(response.data.message));
388 - docGenerateBtnTxt.innerHTML = generateDocLabel;
389 - jQuery('.generate-btn').removeAttr('disabled');
221 + if (response.success && (typeof response.data === 'string')) {
222 + docGenerateBtnTxt.innerHTML = "<?php echo esc_html__('Generated', 'betterdocs'); ?>";
223 + setTimeout(() => {
224 + insertContentToEditor(title, response.data, isOverwrite, keywords);
225 + docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
226 + jQuery('.generate-btn').removeAttr('disabled');
390 227
391 - }
392 - },
393 - error: function(jqXHR, textStatus, errorThrown) {
394 - console.error(jqXHR, textStatus, errorThrown);
228 + // console.log(jQuery('.betterdocs-ai-autowrite-form-container').data('new-doc-page'));
395 229
396 - // Reset the UI so a slow/failed request never leaves a permanent "Generating...".
397 - var timedOut = ( textStatus === 'timeout' ) || ( jqXHR && jqXHR.status === 504 ) || ( jqXHR && jqXHR.status === 0 );
398 - var errMessage = timedOut
399 - ? "<?php echo esc_html__( 'The request timed out before a response came back. The AI may still have generated content on the server — try again, or pick a faster model / lower the token limit.', 'betterdocs' ); ?>"
400 - : "<?php echo esc_html__( 'Something went wrong while generating. Please try again.', 'betterdocs' ); ?>";
230 + // if(jQuery('.betterdocs-ai-autowrite-form-container')?.data('new-doc-page')) {
231 + // docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
232 + // }
233 + }, 2000);
234 + } else {
235 + // alert(response.data.message);
236 + jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
237 + jQuery('#betterdocs-ai-error-message').html(responseMessage(response.data.message));
238 + docGenerateBtnTxt.innerHTML = generateDocLabel;
239 + jQuery('.generate-btn').removeAttr('disabled');
401 240
402 - jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
403 - jQuery('#betterdocs-ai-error-message').html(responseMessage(errMessage));
404 - docGenerateBtnTxt.innerHTML = generateDocLabel;
405 - jQuery('.generate-btn').removeAttr('disabled');
406 - },
407 - });
241 + }
242 + },
243 + error: function(error) {
244 + console.error(error);
245 + },
246 + });
408 247
409 - }
410 - }
248 + }
249 + }
411 250
412 - // Function to update the textarea
413 - function updateTextarea() {
414 - const title = document.getElementById('betterdocs-ai-title').value;
415 - const keywords = document.getElementById('betterdocs-ai-keyword').value;
416 - const sectionOptions = document.getElementById('bd-autowrtite-content-section');
417 - let language = 'English';
251 + // Function to update the textarea
252 + function updateTextarea() {
253 + const title = document.getElementById('betterdocs-ai-title').value;
254 + const keywords = document.getElementById('betterdocs-ai-keyword').value;
255 + const sectionOptions = document.getElementById('bd-autowrtite-content-section');
256 + let language = 'English';
418 257
419 - if (language === '') {
420 - language = 'English';
421 - }
258 + if (language === '') {
259 + language = 'English';
260 + }
422 261
423 - let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
262 + let keywordsText = keywords !== '' ? ` and incorporate the keywords: ${keywords}` : '';
424 263
425 - const contentTextArea = document.getElementById('betterdocs-ai-content');
264 + const contentTextArea = document.getElementById('betterdocs-ai-content');
426 265
427 - if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
428 - jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
429 - }
266 + if (!jQuery('#betterdocs-ai-error-message').parent().hasClass('hidden')) {
267 + jQuery('#betterdocs-ai-error-message').parent().addClass('hidden');
268 + }
430 269
431 - contentTextArea.value = `Write documentation for '${title}'. Cover these topics in depth: ${keywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
432 - }
270 + contentTextArea.value = `Generate a documentation using HTML heading tags for '${title}'. Include relevant details on ${keywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
271 + }
433 272
434 - function convertMarkdownToHTML(markdownContent) {
435 - // Simple Markdown to HTML conversion (you may need to enhance this based on your needs)
436 - const htmlContent = markdownContent
437 - .replace(/^# (.+)$/gm, '<h1>$1</h1>')
438 - .replace(/^## (.+)$/gm, '<h2>$1</h2>')
439 - .replace(/^### (.+)$/gm, '<h3>$1</h3>')
440 - .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
441 - .replace(/\*(.+?)\*/g, '<em>$1</em>');
273 + function convertMarkdownToHTML(markdownContent) {
274 + // Simple Markdown to HTML conversion (you may need to enhance this based on your needs)
275 + const htmlContent = markdownContent
276 + .replace(/^# (.+)$/gm, '<h1>$1</h1>')
277 + .replace(/^## (.+)$/gm, '<h2>$1</h2>')
278 + .replace(/^### (.+)$/gm, '<h3>$1</h3>')
279 + .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
280 + .replace(/\*(.+?)\*/g, '<em>$1</em>');
442 281
443 - return htmlContent;
444 - }
282 + return htmlContent;
283 + }
445 284
446 - function replaceHeadingTitle(content, title, overviewTitle) {
447 - let regex = new RegExp(title, 'g');
448 - let updateContent = content.replace(regex, overviewTitle);
449 - return updateContent;
450 - }
285 + function replaceHeadingTitle(content, title, overviewTitle) {
286 + let regex = new RegExp(title, 'g');
287 + let updateContent = content.replace(regex, overviewTitle);
288 + return updateContent;
289 + }
451 290
452 - function removeFirstHeading(htmlString) {
453 - var newDiv = document.createElement('div');
454 - newDiv.innerHTML = htmlString;
455 - var firstHeading = newDiv.querySelector('h1');
456 - if (firstHeading) {
457 - firstHeading.parentNode.removeChild(firstHeading);
458 - }
459 - return newDiv.innerHTML;
460 - }
291 + function removeFirstHeading(htmlString) {
292 + var newDiv = document.createElement('div');
293 + newDiv.innerHTML = htmlString;
294 + var firstHeading = newDiv.querySelector('h1');
295 + if (firstHeading) {
296 + firstHeading.parentNode.removeChild(firstHeading);
297 + }
298 + return newDiv.innerHTML;
299 + }
461 300
462 301
463 - function escapeHtml(str) {
464 - return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
465 - }
302 + function wrapwithHeighlight(inputString, keywords) {
303 + let modifiedString = inputString.replace(/<(h\d)(.*?)>(.*?)<\/\1>/g, '<$1$2><span class="highlight">$3</span></$1>');
466 304
467 - function escapeRegex(str) {
468 - return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
469 - }
305 + const keywordArray = keywords.split(',').map(keyword => keyword.trim());
470 306
471 - function stripCodeFences(htmlString) {
472 - if (!htmlString) {
473 - return '';
474 - }
475 - return htmlString
476 - .replace(/^\s*```(?:html|HTML)?\s*\n?/, '')
477 - .replace(/\n?\s*```\s*$/, '');
478 - }
307 + keywordArray.forEach(keyword => {
308 + modifiedString = modifiedString.replace(new RegExp(`\\b(${keyword})\\b`, 'gi'), '<span class="highlight">$1</span>');
309 + });
479 310
480 - function wrapwithHeighlight(inputString, keywords) {
481 - if (!inputString) {
482 - return '';
483 - }
311 + return modifiedString;
312 + }
484 313
485 - const container = document.createElement('div');
486 - container.innerHTML = inputString;
314 + function getBodyContent(htmlString) {
315 + var match = htmlString.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
487 316
488 - // Wrap each heading's visible text with the highlight span (skip if already present)
489 - container.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(function (heading) {
490 - if (heading.querySelector('.highlight')) {
491 - return;
492 - }
493 - const text = heading.textContent;
494 - if (!text || !text.trim()) {
495 - return;
496 - }
497 - heading.innerHTML = '<span class="highlight">' + escapeHtml(text) + '</span>';
498 - });
317 + console.log(match[1].replace(/<p>\s+/g, '<p>'));
499 318
500 - // Wrap keywords only inside text nodes — never inside attributes, code, or existing highlights
501 - const keywordList = (keywords || '')
502 - .split(',')
503 - .map(function (k) { return k.trim(); })
504 - .filter(Boolean);
319 + return match ? match[1].replace(/<p>\s+/g, '<p>') : '';
320 + }
505 321
506 - if (keywordList.length) {
507 - const pattern = new RegExp('\\b(' + keywordList.map(escapeRegex).join('|') + ')\\b', 'gi');
508 - const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, {
509 - acceptNode: function (node) {
510 - let parent = node.parentNode;
511 - while (parent && parent !== container) {
512 - if (parent.nodeType === 1) {
513 - const tag = parent.tagName.toLowerCase();
514 - if (tag === 'code' || tag === 'pre') {
515 - return NodeFilter.FILTER_REJECT;
516 - }
517 - if (parent.classList && parent.classList.contains('highlight')) {
518 - return NodeFilter.FILTER_REJECT;
519 - }
520 - }
521 - parent = parent.parentNode;
522 - }
523 - return NodeFilter.FILTER_ACCEPT;
524 - }
525 - });
526 322
527 - const textNodes = [];
528 - let current;
529 - while ((current = walker.nextNode())) {
530 - textNodes.push(current);
531 - }
323 + function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
532 324
533 - textNodes.forEach(function (textNode) {
534 - pattern.lastIndex = 0;
535 - if (!pattern.test(textNode.nodeValue)) {
536 - return;
537 - }
538 - pattern.lastIndex = 0;
539 - const fragmentHost = document.createElement('span');
540 - fragmentHost.innerHTML = escapeHtml(textNode.nodeValue).replace(pattern, '<span class="highlight">$1</span>');
541 - const parent = textNode.parentNode;
542 - while (fragmentHost.firstChild) {
543 - parent.insertBefore(fragmentHost.firstChild, textNode);
544 - }
545 - parent.removeChild(textNode);
546 - });
547 - }
325 + const {
326 + dispatch,
327 + select
328 + } = wp.data;
548 329
549 - return container.innerHTML;
550 - }
330 + htmlContent = getBodyContent(htmlContent);
331 + htmlContent = removeFirstHeading(htmlContent);
332 + htmlContent = wrapwithHeighlight(htmlContent, keywords);
333 + const isPostContent = `<?php echo isset($_GET['post']) ? get_the_content($_GET['post']) : ''; ?>`;
551 334
552 - function getBodyContent(htmlString) {
553 - if (!htmlString) {
554 - return '';
555 - }
556 - const cleaned = stripCodeFences(htmlString);
557 - const match = cleaned.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
558 - if (match) {
559 - return match[1].replace(/<p>\s+/g, '<p>');
560 - }
561 - return cleaned;
562 - }
335 + const blocks = wp.blocks.rawHandler({
336 + HTML: htmlContent
337 + });
563 338
339 + dispatch('core/editor').editPost({
340 + title: title,
341 + });
564 342
343 + const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
565 344
566 - function insertContentToEditor(title, htmlContent, isOverwrite, keywords) {
345 + const allBlocks = select('core/block-editor').getBlocks();
567 346
568 - const {
569 - dispatch,
570 - select
571 - } = wp.data;
347 + if (isOverwrite || isPostContent === '') {
572 348
573 - htmlContent = getBodyContent(htmlContent);
574 - htmlContent = removeFirstHeading(htmlContent);
575 - htmlContent = wrapwithHeighlight(htmlContent, keywords);
576 - const isPostContent = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_content( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
349 + allBlocks.forEach((block) => {
350 + dispatch('core/block-editor').removeBlock(block.clientId);
351 + });
352 + dispatch('core/block-editor').insertBlocks(blocks);
577 353
578 - const blocks = wp.blocks.rawHandler({
579 - HTML: htmlContent
580 - });
354 + } else if (selectedBlockClientId) {
355 + const selectedIndex = select('core/block-editor').getBlockIndex(selectedBlockClientId);
356 + dispatch('core/block-editor').insertBlocks(blocks, selectedIndex + 1);
357 + } else {
358 + dispatch('core/block-editor').insertBlocks(blocks);
359 + }
581 360
582 - dispatch('core/editor').editPost({
583 - title: title,
584 - });
361 + closeWriteWithAIForm('afterInsertContent');
362 + }
585 363
586 - const selectedBlockClientId = select('core/block-editor').getSelectedBlockClientId();
364 + function closeWriteWithAIForm(after) {
365 + jQuery('.betterdocs-ai-autowrite-form-container').addClass('hidden');
366 + jQuery('#betterdocs-ai-autowrite-form-container-overlay').addClass('hidden');
367 + jQuery('.betterdocs-ai-button').addClass('regenerate-btn');
368 + }
587 369
588 - const allBlocks = select('core/block-editor').getBlocks();
589 370
590 - if (isOverwrite || isPostContent === '') {
371 + document.addEventListener('DOMContentLoaded', function() {
591 372
592 - allBlocks.forEach((block) => {
593 - dispatch('core/block-editor').removeBlock(block.clientId);
594 - });
595 - dispatch('core/block-editor').insertBlocks(blocks);
373 + // Subscribe to changes in the editor state
374 + let previousDocsTitle = '';
596 375
597 - } else if (selectedBlockClientId) {
598 - const selectedIndex = select('core/block-editor').getBlockIndex(selectedBlockClientId);
599 - dispatch('core/block-editor').insertBlocks(blocks, selectedIndex + 1);
600 - } else {
601 - dispatch('core/block-editor').insertBlocks(blocks);
602 - }
376 + wp.data.subscribe(() => {
377 + // Get the updated post title
378 + // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
603 379
604 - closeWriteWithAIForm('afterInsertContent');
605 - }
380 + const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
606 381
607 - function closeWriteWithAIForm(after) {
608 - jQuery('.betterdocs-ai-autowrite-form-container').addClass('hidden');
609 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').addClass('hidden');
610 - jQuery('.betterdocs-ai-button').addClass('regenerate-btn');
611 - }
382 + // Check if the title has changed
383 + if (docsTitle !== previousDocsTitle) {
384 + let currentKeywords = jQuery('#betterdocs-ai-keyword').val();
385 + if (!currentKeywords) {
386 + currentKeywords = '{Documentation Keywords}';
387 + }
388 + const currentPrompt = `Generate documentation using HTML heading tags for '${docsTitle?docsTitle:'{Documentation title}'}'. Include relevant details on ${currentKeywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
389 + jQuery('#betterdocs-ai-content').val(currentPrompt);
612 390
391 + jQuery('#betterdocs-ai-title').val(docsTitle);
613 392
614 - document.addEventListener('DOMContentLoaded', function() {
393 + previousDocsTitle = docsTitle;
394 + }
615 395
616 - // Subscribe to changes in the editor state
617 - let previousDocsTitle = '';
618 396
619 - wp.data.subscribe(() => {
620 - // Get the updated post title
621 - // const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
397 + });
398 + });
622 399
623 - const docsTitle = wp.data.select('core/editor').getEditedPostAttribute('title');
624 400
625 - // Check if the title has changed
626 - if (docsTitle !== previousDocsTitle) {
627 - let currentKeywords = jQuery('#betterdocs-ai-keyword').val();
628 - if (!currentKeywords) {
629 - currentKeywords = '{Documentation Keywords}';
630 - }
631 - const currentPrompt = `Write documentation for '${docsTitle?docsTitle:'{Documentation title}'}'. Cover these topics in depth: ${currentKeywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
632 - jQuery('#betterdocs-ai-content').val(currentPrompt);
401 + // This example assumes that this code is executed when your script is loaded.
402 + // You may want to place it within the appropriate context in your application.
633 403
634 - jQuery('#betterdocs-ai-title').val(docsTitle);
635 404
636 - previousDocsTitle = docsTitle;
637 - }
405 + function writeWithAIForm() {
638 406
407 + let title = `<?php echo isset($_GET['post']) ? get_the_title($_GET['post']) : ''; ?>`;
408 + if (docsTitle) {
409 + title = docsTitle;
410 + }
639 411
640 - });
641 - });
412 + const promtTitle = `<?php echo isset($_GET['post']) ? get_the_title($_GET['post']) : '{Documentation Title}'; ?>`;
413 + const titlePlaceholder = "<?php echo esc_attr__('Enter a descriptive title for your documentation.', 'betterdocs'); ?>";
414 + const keywords = "<?php echo esc_attr('{Documentation Keywords}'); ?>";
415 + const keywordsPlaceholder = "<?php echo esc_attr__('Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs'); ?>";
416 + const language = "<?php echo esc_attr('English'); ?>";
417 + const titleLabel = "<?php echo esc_html__('Documentation Title:', 'betterdocs'); ?>";
418 + const keywordLabel = "<?php echo esc_html__('Keywords:', 'betterdocs'); ?>";
419 + const secLabel = "<?php echo esc_html__('# of Sections:', 'betterdocs'); ?>";
420 + const paraLabel = "<?php echo esc_html__('# of Paragraph Per Section: ', 'betterdocs'); ?>";
421 + const langLabel = "<?php echo esc_html__('Language:', 'betterdocs'); ?>";
422 + const promtLabel = "<?php echo esc_html__('Prompt:', 'betterdocs'); ?>";
423 + const promtBtnLabel = "<?php echo esc_html__('Generate Prompt', 'betterdocs'); ?>";
424 + let promtArticleLabel = "<?php echo esc_html__('Generate Doc', 'betterdocs'); ?>";
425 + const checkboxLabel = "<?php echo esc_html__('Overwrite your existing Doc:', 'betterdocs'); ?>";
426 + const nonce = "<?php echo esc_attr(wp_create_nonce('generate_openai_content_nonce')); ?>";
642 427
643 -
644 - // This example assumes that this code is executed when your script is loaded.
645 - // You may want to place it within the appropriate context in your application.
646 -
647 -
648 - function writeWithAIForm() {
649 -
650 - let title = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_title( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
651 - if (docsTitle) {
652 - title = docsTitle;
653 - }
654 -
655 - const promtTitle = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_title( absint( wp_unslash( $_GET['post'] ) ) ) ) : '{Documentation Title}'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
656 - const titlePlaceholder = "<?php echo esc_attr__( 'Enter a descriptive title for your documentation.', 'betterdocs' ); ?>";
657 - const keywords = "<?php echo esc_attr( '{Documentation Keywords}' ); ?>";
658 - const keywordsPlaceholder = "<?php echo esc_attr__( 'Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs' ); ?>";
659 - const language = "<?php echo esc_attr( 'English' ); ?>";
660 - const titleLabel = "<?php echo esc_html__( 'Documentation Title:', 'betterdocs' ); ?>";
661 - const keywordLabel = "<?php echo esc_html__( 'Keywords:', 'betterdocs' ); ?>";
662 - const secLabel = "<?php echo esc_html__( '# of Sections:', 'betterdocs' ); ?>";
663 - const paraLabel = "<?php echo esc_html__( '# of Paragraph Per Section: ', 'betterdocs' ); ?>";
664 - const langLabel = "<?php echo esc_html__( 'Language:', 'betterdocs' ); ?>";
665 - const promtLabel = "<?php echo esc_html__( 'Prompt:', 'betterdocs' ); ?>";
666 - const promtBtnLabel = "<?php echo esc_html__( 'Generate Prompt', 'betterdocs' ); ?>";
667 - let promtArticleLabel = "<?php echo esc_html__( 'Generate Doc', 'betterdocs' ); ?>";
668 - const checkboxLabel = "<?php echo esc_html__( 'Overwrite your existing Doc:', 'betterdocs' ); ?>";
669 - const nonce = "<?php echo esc_attr( wp_create_nonce( 'generate_openai_content_nonce' ) ); ?>";
670 -
671 - <?php
672 - $is_valid = $this->get_api_key();
673 - $disable_field = 'disabled-input-field';
674 - if ( $this->get_api_key() ) {
675 - $disable_field = '';
676 - }
428 + <?php $is_valid = $this->get_api_key();
429 + $disable_field = 'disabled-input-field';
430 + if ($this->get_api_key()) {
431 + $disable_field = '';
432 + }
677 433 ?>
678 434
679 - let hiddenClass = 'hidden';
680 - let newDocPageAtt = 'data-new-doc-page="true"';
681 - const isPostContent = `<?php echo isset( $_GET['post'] ) ? esc_html( get_the_content( absint( wp_unslash( $_GET['post'] ) ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only post id from URL. ?>`;
435 + let hiddenClass = 'hidden';
436 + let newDocPageAtt = 'data-new-doc-page="true"';
437 + const isPostContent = `<?php echo isset($_GET['post']) ? get_the_content($_GET['post']) : ''; ?>`;
682 438
683 - if (isPostContent !== '') {
684 - hiddenClass = '';
685 - newDocPageAtt = '';
686 - }
439 + if (isPostContent !== '') {
440 + hiddenClass = '';
441 + newDocPageAtt = '';
442 + }
687 443
688 444
689 - // const prompt = `Make a knowledge base article with html heading tags about [${title}] in [${language}]. Here is some topic to describe the article: [${keywords}]. and wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
445 + // const prompt = `Make a knowledge base article with html heading tags about [${title}] in [${language}]. Here is some topic to describe the article: [${keywords}]. and wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
690 446
691 - // const prompt = `Create a details knowledge base article in [${language}] about [${title}] with html heading tags. Here is some topic to describe the article: [${keywords}]. And wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
447 + // const prompt = `Create a details knowledge base article in [${language}] about [${title}] with html heading tags. Here is some topic to describe the article: [${keywords}]. And wrap the content with p tag also add a span tag with a class named 'highlight' to all the heading and topic tags in the article.`;
692 448
693 - const prompt = `Write documentation for '${promtTitle}'. Cover these topics in depth: ${keywords}. Use headings, paragraphs, lists, links, code blocks, and tables wherever they help the reader. Follow the output-format rules in the system instructions.`;
449 + const prompt = `Generate a documentation using HTML heading tags for '${promtTitle}'. Include relevant details on ${keywords} in the documentation. Ensure all content is enclosed with <p> tags and apply a <span> tag with the class 'highlight' to headings and topic tags for emphasis.`;
694 450
695 - const aiIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none">
696 - <g clip-path="url(#clip0_2460_1729)">
697 - <path d="M10.3956 18.8608L6.10991 19.2322L6.48134 14.9465L15.3956 6.08936C15.5287 5.95329 15.6876 5.84518 15.863 5.77137C16.0384 5.69756 16.2268 5.65954 16.4171 5.65954C16.6074 5.65954 16.7957 5.69756 16.9711 5.77137C17.1466 5.84518 17.3054 5.95329 17.4385 6.08936L19.2528 7.91793C19.3865 8.05083 19.4926 8.20886 19.565 8.38293C19.6375 8.55701 19.6747 8.74368 19.6747 8.93221C19.6747 9.12075 19.6375 9.30742 19.565 9.48149C19.4926 9.65557 19.3865 9.8136 19.2528 9.9465L10.3956 18.8608ZM1.7042 5.67507C1.20277 5.58793 1.20277 4.86793 1.7042 4.78079C2.59203 4.62626 3.41374 4.21085 4.06456 3.58751C4.71538 2.96417 5.16583 2.16113 5.35848 1.28079L5.38848 1.14221C5.49705 0.647929 6.20277 0.643643 6.31705 1.13936L6.35277 1.29936C6.55248 2.17579 7.0067 2.97367 7.65837 3.59281C8.31005 4.21195 9.13013 4.62475 10.0156 4.77936C10.5199 4.86507 10.5199 5.58936 10.0156 5.67793C9.13005 5.83218 8.3098 6.24465 7.65787 6.86354C7.00594 7.48243 6.5514 8.28014 6.35134 9.1565L6.3142 9.31793C6.20134 9.81221 5.49563 9.80936 5.38705 9.31364L5.35848 9.17507C5.16564 8.29433 4.71476 7.49102 4.06339 6.86764C3.41202 6.24426 2.58969 5.82908 1.70134 5.67507H1.7042Z" stroke="white" stroke-width="1.42857" stroke-linecap="round" stroke-linejoin="round"/>
698 - </g>
699 - <defs>
700 - <clipPath id="clip0_2460_1729">
701 - <rect width="20" height="20" fill="white" transform="translate(0.5)"/>
702 - </clipPath>
703 - </defs>
704 - </svg>`;
451 + const aiIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none">
452 + <g clip-path="url(#clip0_2460_1729)">
453 + <path d="M10.3956 18.8608L6.10991 19.2322L6.48134 14.9465L15.3956 6.08936C15.5287 5.95329 15.6876 5.84518 15.863 5.77137C16.0384 5.69756 16.2268 5.65954 16.4171 5.65954C16.6074 5.65954 16.7957 5.69756 16.9711 5.77137C17.1466 5.84518 17.3054 5.95329 17.4385 6.08936L19.2528 7.91793C19.3865 8.05083 19.4926 8.20886 19.565 8.38293C19.6375 8.55701 19.6747 8.74368 19.6747 8.93221C19.6747 9.12075 19.6375 9.30742 19.565 9.48149C19.4926 9.65557 19.3865 9.8136 19.2528 9.9465L10.3956 18.8608ZM1.7042 5.67507C1.20277 5.58793 1.20277 4.86793 1.7042 4.78079C2.59203 4.62626 3.41374 4.21085 4.06456 3.58751C4.71538 2.96417 5.16583 2.16113 5.35848 1.28079L5.38848 1.14221C5.49705 0.647929 6.20277 0.643643 6.31705 1.13936L6.35277 1.29936C6.55248 2.17579 7.0067 2.97367 7.65837 3.59281C8.31005 4.21195 9.13013 4.62475 10.0156 4.77936C10.5199 4.86507 10.5199 5.58936 10.0156 5.67793C9.13005 5.83218 8.3098 6.24465 7.65787 6.86354C7.00594 7.48243 6.5514 8.28014 6.35134 9.1565L6.3142 9.31793C6.20134 9.81221 5.49563 9.80936 5.38705 9.31364L5.35848 9.17507C5.16564 8.29433 4.71476 7.49102 4.06339 6.86764C3.41202 6.24426 2.58969 5.82908 1.70134 5.67507H1.7042Z" stroke="white" stroke-width="1.42857" stroke-linecap="round" stroke-linejoin="round"/>
454 + </g>
455 + <defs>
456 + <clipPath id="clip0_2460_1729">
457 + <rect width="20" height="20" fill="white" transform="translate(0.5)"/>
458 + </clipPath>
459 + </defs>
460 + </svg>`;
705 461
706 462
707 463
708 - return `
709 - <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
710 - <div class="betterdocs-ai-autowrite-form-content">
711 - <div class="betterdocs-ai-autowrite-top-part">
712 - <div class="autowrite-heading">
713 - <span class="autowrite-icon">
714 - <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
715 - <g clip-path="url(#clip0_2453_20882)">
716 - <path d="M15.8322 30.1765L8.97508 30.7708L9.56936 23.9136L23.8322 9.74219C24.0451 9.52448 24.2993 9.3515 24.58 9.23341C24.8606 9.11531 25.162 9.05447 25.4665 9.05447C25.771 9.05447 26.0724 9.11531 26.3531 9.23341C26.6337 9.3515 26.8879 9.52448 27.1008 9.74219L30.0037 12.6679C30.2176 12.8805 30.3874 13.1334 30.5033 13.4119C30.6192 13.6904 30.6788 13.9891 30.6788 14.2908C30.6788 14.5924 30.6192 14.8911 30.5033 15.1696C30.3874 15.4481 30.2176 15.701 30.0037 15.9136L15.8322 30.1765ZM1.92593 9.07933C1.12365 8.9399 1.12365 7.7879 1.92593 7.64848C3.34647 7.40124 4.6612 6.73658 5.70251 5.73923C6.74382 4.74188 7.46455 3.45703 7.77279 2.04848L7.82079 1.82676C7.99451 1.03591 9.12365 1.02905 9.30651 1.82219L9.36365 2.07819C9.68319 3.48048 10.4099 4.75709 11.4526 5.74772C12.4953 6.73834 13.8074 7.39881 15.2242 7.64619C16.0311 7.78333 16.0311 8.94219 15.2242 9.0839C13.8073 9.33071 12.4949 9.99066 11.4518 10.9809C10.4087 11.9711 9.68146 13.2474 9.36136 14.6496L9.30193 14.9079C9.12136 15.6988 7.99222 15.6942 7.81851 14.901L7.77279 14.6793C7.46424 13.2702 6.74284 11.9849 5.70064 10.9874C4.65845 9.99003 3.34273 9.32574 1.92136 9.07933H1.92593Z" stroke="#E31B54" stroke-width="2.28571" stroke-linecap="round" stroke-linejoin="round"/>
717 - </g>
718 - <defs>
719 - <clipPath id="clip0_2453_20882">
720 - <rect width="32" height="32" fill="white"/>
721 - </clipPath>
722 - </defs>
723 - </svg>
724 - </span>
725 - <h1><?php echo esc_html__( 'Write Documentation with BetterDocs AI', 'betterdocs' ); ?></h1>
464 + return `
465 + <div class="betterdocs-ai-autowrite-form-container hidden" ${newDocPageAtt}>
466 + <div class="betterdocs-ai-autowrite-form-content">
467 + <div class="betterdocs-ai-autowrite-top-part">
468 + <div class="autowrite-heading">
469 + <span class="autowrite-icon">
470 + <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
471 + <g clip-path="url(#clip0_2453_20882)">
472 + <path d="M15.8322 30.1765L8.97508 30.7708L9.56936 23.9136L23.8322 9.74219C24.0451 9.52448 24.2993 9.3515 24.58 9.23341C24.8606 9.11531 25.162 9.05447 25.4665 9.05447C25.771 9.05447 26.0724 9.11531 26.3531 9.23341C26.6337 9.3515 26.8879 9.52448 27.1008 9.74219L30.0037 12.6679C30.2176 12.8805 30.3874 13.1334 30.5033 13.4119C30.6192 13.6904 30.6788 13.9891 30.6788 14.2908C30.6788 14.5924 30.6192 14.8911 30.5033 15.1696C30.3874 15.4481 30.2176 15.701 30.0037 15.9136L15.8322 30.1765ZM1.92593 9.07933C1.12365 8.9399 1.12365 7.7879 1.92593 7.64848C3.34647 7.40124 4.6612 6.73658 5.70251 5.73923C6.74382 4.74188 7.46455 3.45703 7.77279 2.04848L7.82079 1.82676C7.99451 1.03591 9.12365 1.02905 9.30651 1.82219L9.36365 2.07819C9.68319 3.48048 10.4099 4.75709 11.4526 5.74772C12.4953 6.73834 13.8074 7.39881 15.2242 7.64619C16.0311 7.78333 16.0311 8.94219 15.2242 9.0839C13.8073 9.33071 12.4949 9.99066 11.4518 10.9809C10.4087 11.9711 9.68146 13.2474 9.36136 14.6496L9.30193 14.9079C9.12136 15.6988 7.99222 15.6942 7.81851 14.901L7.77279 14.6793C7.46424 13.2702 6.74284 11.9849 5.70064 10.9874C4.65845 9.99003 3.34273 9.32574 1.92136 9.07933H1.92593Z" stroke="#E31B54" stroke-width="2.28571" stroke-linecap="round" stroke-linejoin="round"/>
473 + </g>
474 + <defs>
475 + <clipPath id="clip0_2453_20882">
476 + <rect width="32" height="32" fill="white"/>
477 + </clipPath>
478 + </defs>
479 + </svg>
480 + </span>
481 + <h1><?php echo esc_html__('Write Documentation with BetterDocs AI', 'betterdocs'); ?></h1>
726 482
727 - </div>
728 - <div class="autowrite-subheadding">
729 - <p><?php echo esc_html__( 'Generate documentation effortlessly with BetterDocs AI. Simply input your doc title, keywords, prompt and let the system automatically generate comprehensive documentation tailored to your needs.', 'betterdocs' ); ?></p>
730 - </div>
483 + </div>
484 + <div class="autowrite-subheadding">
485 + <p><?php echo esc_html__('Generate documentation effortlessly with BetterDocs AI. Simply input your doc title, keywords, prompt and let the system automatically generate comprehensive documentation tailored to your needs.', 'betterdocs'); ?></p>
486 + </div>
731 487
732 - <?php if ( empty( $this->get_api_key() ) ): ?>
733 - <div id="betterdocs-ai-message">
734 - <div class="warning-message">
735 - <span class="dashicons dashicons-warning"></span>
736 - <div>
737 - <?php echo wp_kses_post( 'Please Insert your <a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=betterdocs-settings#betterdocs-ai' ) ) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs' ); ?>
738 - </div>
739 - </div>
488 + <?php if (empty($this->get_api_key())) : ?>
489 + <div id="betterdocs-ai-message">
490 + <div class="warning-message">
491 + <span class="dashicons dashicons-warning"></span>
492 + <div>
493 + <?php echo wp_kses_post('Please Insert your <a target="_blank" href="' . esc_url(admin_url('admin.php?page=betterdocs-settings&tab=tab-ai-autowrite')) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs'); ?>
494 + </div>
495 + </div>
740 496
741 - </div>
742 - <?php endif; ?>
497 + </div>
498 + <?php endif; ?>
743 499
744 - <div class="form-group hidden">
745 - <div id="betterdocs-ai-error-message"></div>
746 - </div>
500 + <div class="form-group hidden">
501 + <div id="betterdocs-ai-error-message"></div>
502 + </div>
503 +
504 + </div>
505 + <form id="betterdocs-ai-form" class="<?php echo esc_attr($disable_field); ?>">
506 + <div class="form-inner-content">
507 + <div class="form-group">
508 + <label for="betterdocs-ai-title">${titleLabel}</label>
509 + <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
510 + </div>
747 511
748 - </div>
749 - <form id="betterdocs-ai-form" class="<?php echo esc_attr( $disable_field ); ?>">
750 - <div class="form-inner-content">
751 - <div class="form-group">
752 - <label for="betterdocs-ai-title">${titleLabel}</label>
753 - <input type="text" placeholder="${titlePlaceholder}" id="betterdocs-ai-title" name="betterdocs-ai-title" required value="${title}">
754 - </div>
512 + <div class="form-group">
513 + <label for="betterdocs-ai-keyword">${keywordLabel}</label>
514 + <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
515 + </div>
755 516
756 - <div class="form-group">
757 - <label for="betterdocs-ai-keyword">${keywordLabel}</label>
758 - <input type="text" placeholder="${keywordsPlaceholder}" id="betterdocs-ai-keyword" name="betterdocs-ai-keyword" required>
759 - </div>
517 + <div class="form-group prompt-field">
518 + <label for="betterdocs-ai-content">${promtLabel}</label>
519 + <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
520 + <p class="input-description"><?php echo esc_html__('Ensure you include a clear and detailed prompt to receive the desired output. Follow the guidelines provided for the best results.', 'betterdocs'); ?></p>
521 + </div>
522 + <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
523 + <div class="form-group">
524 + <div class="checkbox-field-label">
525 + <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
526 + <p class="input-description"><?php echo esc_html__('Overwrite the existing doc with the AI Generated Content. If Disabled, new AI Generated content will be added in the section you are currently editing.', 'betterdocs'); ?></p>
527 + </div>
528 +
529 + <div class="checkbox-input-field">
530 + <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
531 + <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
532 + </div>
533 + </div>
534 + </div>
760 535
761 - <div class="form-group prompt-field">
762 - <label for="betterdocs-ai-content">${promtLabel}</label>
763 - <textarea id="betterdocs-ai-content" name="betterdocs-ai-content" rows="6" required>${prompt}</textarea>
764 - <p class="input-description"><?php echo esc_html__( 'Ensure you include a clear and detailed prompt to receive the desired output. Follow the guidelines provided for the best results.', 'betterdocs' ); ?></p>
765 - </div>
766 - <div class="betterdocs-ai-checkbox-field ${hiddenClass}">
767 - <div class="form-group">
768 - <div class="checkbox-field-label">
769 - <label for="betterdocs-ai-checkbox">${checkboxLabel}</label>
770 - <p class="input-description"><?php echo esc_html__( 'Overwrite the existing doc with the AI Generated Content. If Disabled, new AI Generated content will be added in the section you are currently editing.', 'betterdocs' ); ?></p>
771 - </div>
536 + <input type="hidden" name="ai_nonce" value="${nonce}" />
537 + </div>
538 + <div class="generate-button-container">
539 + <button type="submit" class="generate-btn" onclick="generateArticle(event)">
540 + ${aiIcon} <span>${promtArticleLabel}</span>
541 + </button>
542 + </div>
543 + </form>
544 + </div>
772 545
773 - <div class="checkbox-input-field">
774 - <input type="checkbox" id="betterdocs-ai-checkbox" name="betterdocs-ai-checkbox" data-overwrite="false">
775 - <label for="betterdocs-ai-checkbox" class="toggle-label"></label>
776 - </div>
777 - </div>
778 - </div>
546 + <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')">✕</div>
547 + </div>
548 +
549 + <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
550 + `;
551 + }
779 552
780 - <input type="hidden" name="ai_nonce" value="${nonce}" />
781 - </div>
782 - <div class="generate-button-container">
783 - <button type="submit" class="generate-btn" onclick="generateArticle(event)">
784 - ${aiIcon} <span>${promtArticleLabel}</span>
785 - </button>
786 - </div>
787 - </form>
788 - </div>
553 + jQuery(document).on('click', '.regenerate-btn', function() {
554 + jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
555 + jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
556 + });
789 557
790 - <div class="bd-close-button" onclick="closeWriteWithAIForm('afterClosedClicked')">✕</div>
791 - </div>
558 + jQuery(document).ready(function($) {
559 + // Check if we are in the Edit Post screen
560 + if ($('.block-editor-page').length > 0) {
561 + const bdAIButton = $(`<div class="betterdocs-ai-button-container">
562 + <button class="betterdocs-ai-button">
563 + <img src="<?php echo esc_url(BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png'); ?>" alt="<?php echo esc_attr__('betterdocs icon', 'embedpress'); ?>" />
564 + <span><?php echo esc_html__('Write with AI', 'embedpress'); ?></span>
565 + </button>
566 + </div>`);
567 + const closeBtn = $('bd-close-button');
792 568
793 - <div id="betterdocs-ai-autowrite-form-container-overlay" class="hidden"></div>
794 - `;
795 - }
569 + const formHtml = writeWithAIForm();
570 + $(formHtml).addClass('hidden');
796 571
797 - jQuery(document).on('click', '.regenerate-btn', function() {
798 - jQuery('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
799 - jQuery('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
800 - });
572 + $(document).on('click', '.betterdocs-ai-button', function() {
573 + $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
574 + $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
575 + });
801 576
802 - jQuery(document).ready(function($) {
803 - // Check if we are in the Edit Post screen
577 + // $(document).on('click', '.betterdocs-ai-button', function() {
578 + if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
579 + $('body').append(formHtml);
804 580
805 - if ($('.block-editor-page').length > 0) {
581 + // Add event listeners to input elements
582 + document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
583 + document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
584 + // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
585 + // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
586 + // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
587 + }
588 + // });
589 + const btn = document.createElement('button');
590 + wp.data.subscribe(function() {
591 + setTimeout(() => {
592 + if ($('.edit-post-header__settings').length > 0) {
593 + $('.edit-post-header__settings').prepend(bdAIButton);
594 + }
595 + }, 1);
596 + });
597 + }
806 598
807 - const bdAIButton = $(`<div class="betterdocs-ai-button-container">
808 - <button class="betterdocs-ai-button">
809 - <img src="<?php echo esc_url( BETTERDOCS_ABSURL . 'assets/admin/images/betterdocs-icon-white.png' ); ?>" alt="<?php echo esc_attr__( 'betterdocs icon', 'betterdocs' ); ?>" />
810 - <span><?php echo esc_html__( 'Write with AI', 'betterdocs' ); ?></span>
811 - </button>
812 - </div>`);
599 + $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
600 + closeWriteWithAIForm();
601 + });
602 + });
603 + </script>
813 604
605 + <style>
606 + .hidden {
607 + display: none !important;
608 + }
814 609
815 - const closeBtn = $('bd-close-button');
610 + .disabled-input-field input,
611 + .disabled-input-field textarea,
612 + .disabled-input-field button,
613 + .disabled-input-field label {
614 + pointer-events: none;
615 + opacity: 0.6;
616 + }
816 617
817 - const formHtml = writeWithAIForm();
818 - $(formHtml).addClass('hidden');
618 + .disabled-input-field label {
619 + opacity: 1;
620 + }
819 621
820 - $(document).on('click', '.betterdocs-ai-button', function() {
821 - $('.betterdocs-ai-autowrite-form-container').removeClass('hidden');
822 - $('#betterdocs-ai-autowrite-form-container-overlay').removeClass('hidden');
823 - });
622 + .betterdocs-ai-button-container {
623 + margin-left: 10px;
624 + }
824 625
825 - // $(document).on('click', '.betterdocs-ai-button', function() {
826 - if ($('.betterdocs-ai-autowrite-form-container').length < 1) {
827 - $('body').append(formHtml);
626 + .autowrite-icon {
627 + display: flex;
628 + align-items: center;
629 + width: 55px;
630 + height: 55px;
631 + background: #FFE4E8;
632 + justify-content: center;
633 + border-radius: 50px;
634 + }
828 635
829 - // Add event listeners to input elements
830 - document.getElementById('betterdocs-ai-title').addEventListener('input', updateTextarea);
831 - document.getElementById('betterdocs-ai-keyword').addEventListener('input', updateTextarea);
832 - // document.getElementById('bd-autowrtite-content-section').addEventListener('change', updateTextarea);
833 - // document.getElementById('bd-autowrtite-content-paragraph').addEventListener('change', updateTextarea);
834 - // document.getElementById('betterdocs-ai-language').addEventListener('input', updateTextarea);
835 - }
836 - // });
837 - const btn = document.createElement('button');
838 - wp.data.subscribe(function() {
839 - setTimeout(() => {
840 - if ($('.edit-post-header__settings').length > 0) {
841 - $('.edit-post-header__settings').prepend(bdAIButton);
842 - } else if ($('.editor-header__settings').length > 0) {
843 - $('.editor-header__settings').prepend(bdAIButton);
844 - }
636 + .autowrite-icon svg {
637 + width: 28px;
638 + height: 28px;
639 + }
845 640
846 - }, 1);
847 - });
848 - }
641 + .autowrite-heading {
642 + display: flex;
643 + gap: 10px;
644 + align-items: center;
645 + }
849 646
850 - $(document).on('click', '#betterdocs-ai-autowrite-form-container-overlay', function() {
851 - closeWriteWithAIForm();
852 - });
853 - });
854 - </script>
647 + .autowrite-heading h1 {
648 + color: #1D2939;
649 + font-family: 'IBM Plex Sans', sans-serif;
650 + font-size: 24px;
651 + font-style: normal;
652 + font-weight: 500;
653 + line-height: normal;
654 + margin: 0;
655 + }
855 656
856 - <style>
857 - .hidden {
858 - display: none !important;
859 - }
657 + .autowrite-heading p,
658 + form#betterdocs-ai-form p {
659 + margin: 0;
660 + margin-bottom: 24px;
661 + }
860 662
861 - .disabled-input-field input,
862 - .disabled-input-field textarea,
863 - .disabled-input-field button,
864 - .disabled-input-field label {
865 - pointer-events: none;
866 - opacity: 0.6;
867 - }
663 + .autowrite-subheadding p {
664 + font-family: 'IBM Plex Sans', sans-serif;
665 + font-size: 14px;
666 + }
868 667
869 - .disabled-input-field label {
870 - opacity: 1;
871 - }
668 + .prompt-field .input-description {
669 + margin: 0 !important;
670 + }
872 671
873 - .betterdocs-ai-button-container {
874 - margin-left: 10px;
875 - white-space: nowrap;
876 - max-width: 145px;
877 - }
672 + .autowrite-heading p {
673 + color: #475467;
674 + font-family: 'IBM Plex Sans', sans-serif;
675 + font-size: 16px;
676 + font-style: normal;
677 + font-weight: 400;
678 + }
878 679
879 - .autowrite-icon {
880 - display: flex;
881 - align-items: center;
882 - width: 55px;
883 - height: 55px;
884 - background: #FFE4E8;
885 - justify-content: center;
886 - border-radius: 50px;
887 - }
680 + .betterdocs-ai-button {
681 + background: #00B884;
682 + border: 1px solid transparent;
683 + color: #fff;
684 + box-shadow: none;
685 + font-size: 12px;
686 + margin-right: 8px;
687 + padding: 0px 15px;
688 + cursor: pointer;
689 + border-radius: 3px;
690 + height: 38px;
691 + display: flex;
692 + align-items: center;
693 + justify-content: space-between;
694 + gap: 10px;
695 + }
888 696
889 - .autowrite-icon svg {
890 - width: 28px;
891 - height: 28px;
892 - }
697 + .betterdocs-ai-button img {
698 + width: 20px;
699 + height: 20px;
700 + }
893 701
894 - .autowrite-heading {
895 - display: flex;
896 - gap: 10px;
897 - align-items: center;
898 - }
702 + .betterdocs-ai-autowrite-form-container {
703 + position: fixed;
704 + top: 50%;
705 + left: 50%;
706 + transform: translate(-50%, -50%);
707 + z-index: 100001;
708 + width: 650px;
709 + margin: 0 auto;
710 + background-color: #fff;
711 + border-radius: 5px;
712 + font-family: 'IBM Plex Sans', sans-serif;
713 + /* max-height: 600px; */
714 + max-height: 750px;
715 + max-width: 100%;
716 + }
899 717
900 - .autowrite-heading h1 {
901 - color: #1D2939;
902 - font-family: 'IBM Plex Sans', sans-serif;
903 - font-size: 24px;
904 - font-style: normal;
905 - font-weight: 500;
906 - line-height: normal;
907 - margin: 0;
908 - }
718 + .betterdocs-ai-autowrite-form-content {
719 + background-color: #fff;
720 + padding: 20px 0px;
721 + border-radius: 5px;
722 + padding-bottom: 0;
723 + overflow: auto;
724 + /* max-height: 700px; */
725 + height: 100%;
909 726
910 - .autowrite-heading p,
911 - form#betterdocs-ai-form p {
912 - margin: 0;
913 - margin-bottom: 24px;
914 - }
727 + }
915 728
916 - .autowrite-subheadding p {
917 - font-family: 'IBM Plex Sans', sans-serif;
918 - font-size: 14px;
919 - }
729 + .betterdocs-ai-autowrite-top-part {
730 + /* padding-bottom: 20px; */
731 + border-bottom: 1px solid #ddd;
732 + /* margin-bottom: 20px; */
733 + padding: 0 40px;
734 + }
920 735
921 - .prompt-field .input-description {
922 - margin: 0 !important;
923 - }
736 + #betterdocs-ai-form {
737 + display: flex;
738 + flex-direction: column;
739 + /* height: 100%; */
740 + overflow: hidden;
741 + }
924 742
925 - .autowrite-heading p {
926 - color: #475467;
927 - font-family: 'IBM Plex Sans', sans-serif;
928 - font-size: 16px;
929 - font-style: normal;
930 - font-weight: 400;
931 - }
743 + .form-inner-content {
744 + overflow: auto;
745 + height: 100%;
746 + max-height: 435px;
747 + /* max-height: 330px; */
748 + padding: 0 40px;
749 + }
932 750
933 - .betterdocs-ai-button {
934 - background: #00B884;
935 - border: 1px solid transparent;
936 - color: #fff;
937 - box-shadow: none;
938 - font-size: 12px;
939 - margin-right: 8px;
940 - padding: 0px 15px;
941 - cursor: pointer;
942 - border-radius: 3px;
943 - height: 38px;
944 - display: flex;
945 - align-items: center;
946 - justify-content: space-between;
947 - gap: 10px;
948 - width: 135px;
949 - }
751 + .form-inner-content>.form-group {
752 + margin-top: 20px;
753 + }
950 754
951 - .betterdocs-ai-button img {
952 - width: 20px;
953 - height: 20px;
954 - }
955 755
956 - .betterdocs-ai-autowrite-form-container {
957 - position: fixed;
958 - top: 50%;
959 - left: 50%;
960 - transform: translate(-50%, -50%);
961 - z-index: 100001;
962 - width: 650px;
963 - margin: 0 auto;
964 - background-color: #fff;
965 - border-radius: 5px;
966 - font-family: 'IBM Plex Sans', sans-serif;
967 - /* max-height: 600px; */
968 - max-height: 750px;
969 - max-width: 100%;
970 - }
756 + #betterdocs-ai-autowrite-form-container-overlay {
757 + position: fixed;
758 + top: 0;
759 + right: 0;
760 + bottom: 0;
761 + left: 0;
762 + background-color: rgba(0, 0, 0, .7);
763 + z-index: 100000;
764 + }
971 765
972 - .betterdocs-ai-autowrite-form-content {
973 - background-color: #fff;
974 - padding: 20px 0px;
975 - border-radius: 5px;
976 - padding-bottom: 0;
977 - overflow: auto;
978 - /* max-height: 700px; */
979 - height: 100%;
980 766
981 - }
982 767
983 - .betterdocs-ai-autowrite-top-part {
984 - /* padding-bottom: 20px; */
985 - border-bottom: 1px solid #ddd;
986 - /* margin-bottom: 20px; */
987 - padding: 0 40px;
988 - }
768 + #betterdocs-ai-form {
769 + display: flex;
770 + flex-direction: column;
771 + }
989 772
990 - #betterdocs-ai-form {
991 - display: flex;
992 - flex-direction: column;
993 - /* height: 100%; */
994 - overflow: hidden;
995 - }
773 + #betterdocs-ai-form .form-group {
774 + margin-bottom: 24px;
775 + }
996 776
997 - .form-inner-content {
998 - overflow: auto;
999 - height: 100%;
1000 - max-height: 435px;
1001 - /* max-height: 330px; */
1002 - padding: 0 40px;
1003 - }
777 + #betterdocs-ai-form .bd-aiform-flex {
778 + display: flex;
779 + justify-content: space-between;
780 + }
1004 781
1005 - .form-inner-content>.form-group {
1006 - margin-top: 20px;
1007 - }
782 + #betterdocs-ai-form label {
783 + font-weight: 600;
784 + margin-bottom: 5px;
785 + display: block;
786 + font-size: 14px;
787 + line-height: 20px;
788 + }
1008 789
790 + select#bd-autowrtite-content-section,
791 + #bd-autowrtite-content-paragraph,
792 + #betterdocs-ai-language {
793 + width: 150px !important;
794 + height: 40px;
795 + }
1009 796
1010 - #betterdocs-ai-autowrite-form-container-overlay {
1011 - position: fixed;
1012 - top: 0;
1013 - right: 0;
1014 - bottom: 0;
1015 - left: 0;
1016 - background-color: rgba(0, 0, 0, .7);
1017 - z-index: 100000;
1018 - }
797 + #betterdocs-ai-form input[type="text"],
798 + #betterdocs-ai-form textarea {
799 + width: 100%;
800 + padding: 8px;
801 + box-sizing: border-box;
802 + border: 1px solid #D0D5DD;
803 + border-radius: 4px;
804 + color: #667085;
805 + font-weight: 400;
806 + }
1019 807
808 + /* Override autofill text color */
809 + #betterdocs-ai-form input:-webkit-autofill {
810 + -webkit-text-fill-color: #667085 !important;
811 + }
1020 812
813 + #betterdocs-ai-form input::placeholder {
814 + color: #acb2bf;
815 + }
1021 816
1022 - #betterdocs-ai-form {
1023 - display: flex;
1024 - flex-direction: column;
1025 - }
817 + #betterdocs-ai-form textarea {
818 + color: #667085;
819 + }
1026 820
1027 - #betterdocs-ai-form .form-group {
1028 - margin-bottom: 24px;
1029 - }
821 + #betterdocs-ai-form input:focus,
822 + #betterdocs-ai-form textarea:focus {
823 + box-shadow: none;
824 + }
1030 825
1031 - #betterdocs-ai-form .bd-aiform-flex {
1032 - display: flex;
1033 - justify-content: space-between;
1034 - }
826 + #betterdocs-ai-form textarea:focus {
827 + color: inherit;
828 + box-shadow: none;
1035 829
1036 - #betterdocs-ai-form label {
1037 - font-weight: 600;
1038 - margin-bottom: 5px;
1039 - display: block;
1040 - font-size: 14px;
1041 - line-height: 20px;
1042 - }
830 + }
1043 831
1044 - select#bd-autowrtite-content-section,
1045 - #bd-autowrtite-content-paragraph,
1046 - #betterdocs-ai-language {
1047 - width: 150px !important;
1048 - height: 40px;
1049 - }
1050 832
1051 - #betterdocs-ai-form input[type="text"],
1052 - #betterdocs-ai-form textarea {
1053 - width: 100%;
1054 - padding: 8px;
1055 - box-sizing: border-box;
1056 - border: 1px solid #D0D5DD;
1057 - border-radius: 4px;
1058 - color: #667085;
1059 - font-weight: 400;
1060 - }
833 + .generate-button-container {
834 + position: sticky;
835 + bottom: 0px;
836 + width: 100%;
837 + margin-left: 0;
838 + z-index: 999999 !important;
839 + padding: 20px 0;
840 + display: flex;
841 + justify-content: end;
842 + border-top: 1px solid #ddd;
843 + background: white;
844 + border-bottom-right-radius: 5px;
845 + border-bottom-left-radius: 5px;
846 + }
1061 847
1062 - /* Override autofill text color */
1063 - #betterdocs-ai-form input:-webkit-autofill {
1064 - -webkit-text-fill-color: #667085 !important;
1065 - }
848 + .generate-button-container button {
849 + display: flex;
850 + gap: 8px;
851 + align-items: center;
852 + justify-content: center;
853 + opacity: 1 !important;
854 + margin-right: 40px;
855 + }
1066 856
1067 - #betterdocs-ai-form input::placeholder {
1068 - color: #acb2bf;
1069 - }
857 + .input-description {
858 + font-size: 14px;
859 + color: #667085;
860 + }
1070 861
1071 - #betterdocs-ai-form textarea {
1072 - color: #667085;
1073 - }
862 + .betterdocs-ai-checkbox-field .form-group {
863 + display: flex;
864 + align-items: start;
865 + /* gap: 200px; */
866 + justify-content: space-between;
867 + }
1074 868
1075 - #betterdocs-ai-form input:focus,
1076 - #betterdocs-ai-form textarea:focus {
1077 - box-shadow: none;
1078 - }
869 + .betterdocs-ai-checkbox-field input {
870 + width: 20px;
871 + height: 20px;
872 + }
1079 873
1080 - #betterdocs-ai-form textarea:focus {
1081 - color: inherit;
1082 - box-shadow: none;
874 + /* Add this CSS to your existing stylesheet or create a new one */
1083 875
1084 - }
876 + .betterdocs-ai-checkbox-field {
877 + position: relative;
878 + font-size: 16px;
879 + /* Adjust font size as needed */
880 + }
1085 881
882 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
883 + padding: 2px;
884 + }
1086 885
1087 - .generate-button-container {
1088 - position: sticky;
1089 - bottom: 0px;
1090 - width: 100%;
1091 - margin-left: 0;
1092 - z-index: 999999 !important;
1093 - padding: 20px 0;
1094 - display: flex;
1095 - justify-content: end;
1096 - border-top: 1px solid #ddd;
1097 - background: white;
1098 - border-bottom-right-radius: 5px;
1099 - border-bottom-left-radius: 5px;
1100 - }
886 + .betterdocs-ai-checkbox-field input[type=checkbox] {
887 + border: 1px solid #00b884;
888 + }
1101 889
1102 - .generate-button-container button {
1103 - display: flex;
1104 - gap: 8px;
1105 - align-items: center;
1106 - justify-content: center;
1107 - opacity: 1 !important;
1108 - margin-right: 40px;
1109 - }
890 + .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
891 + content: '\2713';
892 + color: #00b884;
893 + }
1110 894
1111 - .input-description {
1112 - font-size: 14px;
1113 - color: #667085;
1114 - }
895 + /* Change the default checkbox color */
896 + .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
897 + -webkit-appearance: none;
898 + /* WebKit/Blink Browsers */
899 + -moz-appearance: none;
900 + /* Firefox */
901 + appearance: none;
902 + border: 1px solid #00b884;
903 + /* Set the height of the checkbox */
904 + /* Optional: Round the corners */
905 + outline: none;
906 + /* Remove the default outline */
907 + }
1115 908
1116 - .betterdocs-ai-checkbox-field .form-group {
1117 - display: flex;
1118 - align-items: start;
1119 - /* gap: 200px; */
1120 - justify-content: space-between;
1121 - }
909 + /* Style the checked state */
910 + .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
911 + /* Set the background color when checked */
912 + border: 1px solid #00b884;
913 + /* Set the border color when checked */
914 + }
1122 915
1123 - .betterdocs-ai-checkbox-field input {
1124 - width: 20px;
1125 - height: 20px;
1126 - }
916 + .checkbox-field-label {
917 + width: calc(100% - 150px);
918 + }
1127 919
1128 - /* Add this CSS to your existing stylesheet or create a new one */
920 + .checkbox-field-label p {
921 + margin: 0 !important;
922 + }
1129 923
1130 - .betterdocs-ai-checkbox-field {
1131 - position: relative;
1132 - font-size: 16px;
1133 - /* Adjust font size as needed */
1134 - }
924 + .checkbox-input-field {
925 + width: 300px;
926 + text-align: right;
927 + }
1135 928
1136 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1137 - padding: 2px;
1138 - }
929 + .checkbox-input-field {
930 + position: relative;
931 + display: inline-block;
932 + width: 60px;
933 + height: 34px;
934 + }
1139 935
1140 - .betterdocs-ai-checkbox-field input[type=checkbox] {
1141 - border: 1px solid #00b884;
1142 - }
936 + .checkbox-input-field input {
937 + display: none;
938 + }
1143 939
1144 - .betterdocs-ai-checkbox-field input[type=checkbox]:checked::before {
1145 - content: '\2713';
1146 - color: #00b884;
1147 - }
940 + .toggle-label {
941 + position: absolute;
942 + cursor: pointer;
943 + top: 0;
944 + left: 0;
945 + right: 0;
946 + bottom: 0;
947 + background-color: #ccc;
948 + border-radius: 34px;
949 + transition: background-color 0.3s;
950 + scale: .9;
951 + width: 52px;
952 + height: 26px;
953 + }
1148 954
1149 - /* Change the default checkbox color */
1150 - .betterdocs-ai-checkbox-field input[type="checkbox"]:hover {
1151 - -webkit-appearance: none;
1152 - /* WebKit/Blink Browsers */
1153 - -moz-appearance: none;
1154 - /* Firefox */
1155 - appearance: none;
1156 - border: 1px solid #00b884;
1157 - /* Set the height of the checkbox */
1158 - /* Optional: Round the corners */
1159 - outline: none;
1160 - /* Remove the default outline */
1161 - }
1162 955
1163 - /* Style the checked state */
1164 - .betterdocs-ai-checkbox-field input[type="checkbox"]:checked {
1165 - /* Set the background color when checked */
1166 - border: 1px solid #00b884;
1167 - /* Set the border color when checked */
1168 - }
956 + .checkbox-input-field input:checked+.toggle-label {
957 + background-color: #00b884;
958 + }
1169 959
1170 - .checkbox-field-label {
1171 - width: calc(100% - 150px);
1172 - }
960 + .toggle-label:after {
961 + content: "";
962 + position: absolute;
963 + height: 22px;
964 + width: 22px;
965 + left: 2px;
966 + bottom: 2px;
967 + background-color: white;
968 + border-radius: 50%;
969 + transition: transform 0.3s;
970 + }
1173 971
1174 - .checkbox-field-label p {
1175 - margin: 0 !important;
1176 - }
972 + .checkbox-input-field input:checked+.toggle-label:after {
973 + transform: translateX(26px);
974 + }
1177 975
1178 - .checkbox-input-field {
1179 - width: 300px;
1180 - text-align: right;
1181 - }
976 + .generate-btn,
977 + .prompt-btn,
978 + .keep-btn {
979 + background-color: #00b884;
980 + color: #fff;
981 + border: none;
982 + padding: 10px 15px;
983 + text-align: center;
984 + text-decoration: none;
985 + display: inline-block;
986 + font-size: 16px;
987 + cursor: pointer;
988 + border-radius: 4px;
989 + }
1182 990
1183 - .checkbox-input-field {
1184 - position: relative;
1185 - display: inline-block;
1186 - width: 60px;
1187 - height: 34px;
1188 - }
991 + .generate-btn[disabled] {
992 + cursor: unset;
993 + }
1189 994
1190 - .checkbox-input-field input {
1191 - display: none;
1192 - }
995 + .bd-close-button {
996 + cursor: pointer;
997 + font-size: 18px;
998 + font-weight: bold;
999 + float: right;
1000 + position: absolute;
1001 + right: 1px;
1002 + top: 1px;
1003 + padding: 10px;
1004 + background: #ffffff;
1005 + border-radius: 25px;
1006 + width: 20px;
1007 + height: 20px;
1008 + display: flex;
1009 + align-items: center;
1010 + justify-content: center;
1011 + color: #281617;
1012 + right: -60px;
1013 + }
1193 1014
1194 - .toggle-label {
1195 - position: absolute;
1196 - cursor: pointer;
1197 - top: 0;
1198 - left: 0;
1199 - right: 0;
1200 - bottom: 0;
1201 - background-color: #ccc;
1202 - border-radius: 34px;
1203 - transition: background-color 0.3s;
1204 - scale: .9;
1205 - width: 52px;
1206 - height: 26px;
1207 - }
1015 + div#betterdocs-ai-error-message,
1016 + #betterdocs-ai-message {
1017 + font-size: 14px;
1018 + font-family: 'IBM Plex Sans', sans-serif;
1019 + color: #667085;
1020 + margin-bottom: 20px;
1021 + }
1208 1022
1023 + div#betterdocs-ai-error-message a,
1024 + #betterdocs-ai-message a {
1025 + text-decoration: none;
1026 + font-weight: 600;
1027 + }
1209 1028
1210 - .checkbox-input-field input:checked+.toggle-label {
1211 - background-color: #00b884;
1212 - }
1029 + div#betterdocs-ai-error-message a:focus,
1030 + #betterdocs-ai-message a:focus {
1031 + outline: none;
1032 + box-shadow: none;
1033 + color: #2271b1;
1034 + }
1213 1035
1214 - .toggle-label:after {
1215 - content: "";
1216 - position: absolute;
1217 - height: 22px;
1218 - width: 22px;
1219 - left: 2px;
1220 - bottom: 2px;
1221 - background-color: white;
1222 - border-radius: 50%;
1223 - transition: transform 0.3s;
1224 - }
1036 + #betterdocs-ai-message span {
1037 + color: #d63638;
1038 + }
1225 1039
1226 - .checkbox-input-field input:checked+.toggle-label:after {
1227 - transform: translateX(26px);
1228 - }
1040 + .warning-message {
1041 + display: flex;
1042 + align-items: center;
1043 + gap: 10px;
1044 + background: #fbebed;
1045 + padding: 12px;
1046 + border-radius: 5px;
1047 + font-size: 14px;
1048 + line-height: 1.4em;
1049 + border-left: 4px solid #d63638;
1050 + }
1229 1051
1230 - .generate-btn,
1231 - .prompt-btn,
1232 - .keep-btn {
1233 - background-color: #00b884;
1234 - color: #fff;
1235 - border: none;
1236 - padding: 10px 15px;
1237 - text-align: center;
1238 - text-decoration: none;
1239 - display: inline-block;
1240 - font-size: 16px;
1241 - cursor: pointer;
1242 - border-radius: 4px;
1243 - }
1052 + .warning-message svg {
1053 + width: 20px;
1054 + height: 20px;
1055 + }
1244 1056
1245 - .generate-btn[disabled] {
1246 - cursor: unset;
1247 - }
1057 + .warning-message span {
1058 + color: #d63638;
1059 + }
1248 1060
1249 - .bd-close-button {
1250 - cursor: pointer;
1251 - font-size: 18px;
1252 - font-weight: bold;
1253 - float: right;
1254 - position: absolute;
1255 - top: -16px;
1256 - border-radius: 50%;
1257 - background: #ffffff;
1258 - width: 40px;
1259 - height: 40px;
1260 - display: flex;
1261 - align-items: center;
1262 - justify-content: center;
1263 - color: #281617;
1264 - right: -42px;
1265 - }
1061 + .warning-message .footer-message {
1062 + width: calc(100% - 20px);
1063 + }
1266 1064
1267 - div#betterdocs-ai-error-message,
1268 - #betterdocs-ai-message {
1269 - font-size: 14px;
1270 - font-family: 'IBM Plex Sans', sans-serif;
1271 - color: #667085;
1272 - margin-bottom: 20px;
1273 - }
1065 + @media only screen and (max-width: 991px) {
1066 + .betterdocs-ai-autowrite-form-container {
1067 + left: 0;
1068 + right: 0;
1069 + transform: translate(0%, -50%);
1070 + }
1274 1071
1275 - div#betterdocs-ai-error-message a,
1276 - #betterdocs-ai-message a {
1277 - text-decoration: none;
1278 - font-weight: 600;
1279 - }
1072 + .betterdocs-ai-autowrite-form-content {
1073 + overflow-x: auto;
1074 + }
1075 + }
1280 1076
1281 - div#betterdocs-ai-error-message a:focus,
1282 - #betterdocs-ai-message a:focus {
1283 - outline: none;
1284 - box-shadow: none;
1285 - color: #2271b1;
1286 - }
1077 + @media only screen and (max-width: 740px) {
1287 1078
1288 - #betterdocs-ai-message span {
1289 - color: #d63638;
1290 - }
1079 + /* .bd-close-button {
1080 + right: px;
1081 + top: 1px;
1082 + border-radius: 5px;
1083 + width: 12px;
1084 + height: 12px;
1085 + color: #ffffff;
1086 + background: #00b884;
1087 + } */
1088 + .bd-close-button {
1089 + right: 0px;
1090 + top: 0px;
1091 + width: 12px;
1092 + height: 12px;
1093 + font-size: 14px;
1094 + }
1291 1095
1292 - .warning-message {
1293 - display: flex;
1294 - align-items: center;
1295 - gap: 10px;
1296 - background: #fbebed;
1297 - padding: 12px;
1298 - border-radius: 5px;
1299 - font-size: 14px;
1300 - line-height: 1.4em;
1301 - border-left: 4px solid #d63638;
1302 - }
1303 -
1304 - .warning-message svg {
1305 - width: 20px;
1306 - height: 20px;
1307 - }
1308 -
1309 - .warning-message span {
1310 - color: #d63638;
1311 - }
1312 -
1313 - .warning-message .footer-message {
1314 - width: calc(100% - 20px);
1315 - }
1316 -
1317 - @media only screen and (max-width: 991px) {
1318 - .betterdocs-ai-autowrite-form-container {
1319 - left: 0;
1320 - right: 0;
1321 - transform: translate(0%, -50%);
1322 - }
1323 -
1324 - .betterdocs-ai-autowrite-form-content {
1325 - overflow-x: auto;
1326 - }
1327 - }
1328 -
1329 - @media only screen and (max-width: 740px) {
1330 -
1331 - /* .bd-close-button {
1332 - right: px;
1333 - top: 1px;
1334 - border-radius: 5px;
1335 - width: 12px;
1336 - height: 12px;
1337 - color: #ffffff;
1338 - background: #00b884;
1339 - } */
1340 - .bd-close-button {
1341 - right: 0px;
1342 - top: 0px;
1343 - width: 12px;
1344 - height: 12px;
1345 - font-size: 14px;
1346 - }
1347 -
1348 - }
1349 - </style>
1350 - <?php
1351 1096 }
1352 - }
1097 + </style>
1098 +<?php
1099 + }
1100 +}