File manager - Edit - /home/premiey/www/wp-includes/images/media/ai.tar
Back
module.php 0000666 00000032220 15165343774 0006564 0 ustar 00 <?php namespace Elementor\Modules\Ai; use Elementor\Core\Base\Module as BaseModule; use Elementor\Core\Common\Modules\Connect\Module as ConnectModule; use Elementor\Modules\Ai\Connect\Ai; use Elementor\Plugin; use Elementor\User; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Module extends BaseModule { public function get_name() { return 'ai'; } public function __construct() { parent::__construct(); add_action( 'elementor/connect/apps/register', function ( ConnectModule $connect_module ) { $connect_module->register_app( 'ai', Ai::get_class_name() ); } ); add_action( 'elementor/ajax/register_actions', function( $ajax ) { $ajax->register_ajax_action( 'ai_get_user_information', [ $this, 'ajax_ai_get_user_information' ] ); $ajax->register_ajax_action( 'ai_get_completion_text', [ $this, 'ajax_ai_get_completion_text' ] ); $ajax->register_ajax_action( 'ai_get_edit_text', [ $this, 'ajax_ai_get_edit_text' ] ); $ajax->register_ajax_action( 'ai_get_custom_code', [ $this, 'ajax_ai_get_custom_code' ] ); $ajax->register_ajax_action( 'ai_get_custom_css', [ $this, 'ajax_ai_get_custom_css' ] ); $ajax->register_ajax_action( 'ai_set_get_started', [ $this, 'ajax_ai_set_get_started' ] ); $ajax->register_ajax_action( 'ai_set_status_feedback', [ $this, 'ajax_ai_set_status_feedback' ] ); $ajax->register_ajax_action( 'ai_get_image_prompt_enhancer', [ $this, 'ajax_ai_get_image_prompt_enhancer' ] ); $ajax->register_ajax_action( 'ai_get_text_to_image', [ $this, 'ajax_ai_get_text_to_image' ] ); $ajax->register_ajax_action( 'ai_get_image_to_image', [ $this, 'ajax_ai_get_image_to_image' ] ); $ajax->register_ajax_action( 'ai_get_image_to_image_mask', [ $this, 'ajax_ai_get_image_to_image_mask' ] ); $ajax->register_ajax_action( 'ai_get_image_to_image_outpainting', [ $this, 'ajax_ai_get_image_to_image_outpainting' ] ); $ajax->register_ajax_action( 'ai_get_image_to_image_upscale', [ $this, 'ajax_ai_get_image_to_image_upscale' ] ); $ajax->register_ajax_action( 'ai_upload_image', [ $this, 'ajax_ai_upload_image' ] ); } ); add_action( 'elementor/editor/before_enqueue_scripts', function() { wp_enqueue_script( 'elementor-ai', $this->get_js_assets_url( 'ai' ), [ 'elementor-common', 'elementor-editor-modules', 'elementor-editor-document', 'elementor-packages-ui', 'elementor-packages-icons', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai', 'ElementorAiConfig', [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); } ); add_action( 'elementor/editor/after_enqueue_styles', function() { wp_enqueue_style( 'elementor-ai', $this->get_css_assets_url( 'modules/ai/editor' ), [], ELEMENTOR_VERSION ); } ); } private function get_ai_connect_url() { $app = $this->get_ai_app(); return $app->get_admin_url( 'authorize', [ 'utm_source' => 'ai-popup', 'utm_campaign' => 'connect-account', 'utm_medium' => 'wp-dash', 'source' => 'generic', ] ); } public function ajax_ai_get_user_information( $data ) { $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { return [ 'is_connected' => false, 'connect_url' => $this->get_ai_connect_url(), ]; } $user_usage = wp_parse_args( $app->get_usage(), [ 'hasAiSubscription' => false, 'usedQuota' => 0, 'quota' => 100, ] ); return [ 'is_connected' => true, 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'usage' => $user_usage, ]; } private function verify_permissions( $editor_post_id ) { $document = Plugin::$instance->documents->get( $editor_post_id ); if ( ! $document ) { throw new \Exception( 'Document not found' ); } if ( ! $document->is_built_with_elementor() || ! $document->is_editable_by_current_user() ) { throw new \Exception( 'Access denied' ); } } public function ajax_ai_get_image_prompt_enhancer( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_image_prompt_enhanced( $data['prompt'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_completion_text( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_completion_text( $data['prompt'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } private function get_ai_app() : Ai { return Plugin::$instance->common->get_component( 'connect' )->get_app( 'ai' ); } public function ajax_ai_get_edit_text( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['input'] ) ) { throw new \Exception( 'Missing input' ); } if ( empty( $data['instruction'] ) ) { throw new \Exception( 'Missing instruction' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_edit_text( $data['input'], $data['instruction'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_custom_code( $data ) { $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['language'] ) ) { throw new \Exception( 'Missing language' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_custom_code( $data['prompt'], $data['language'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_custom_css( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['html_markup'] ) ) { $data['html_markup'] = ''; } if ( empty( $data['element_id'] ) ) { throw new \Exception( 'Missing element_id' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_custom_css( $data['prompt'], $data['html_markup'], $data['element_id'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_set_get_started( $data ) { $app = $this->get_ai_app(); User::set_introduction_viewed( [ 'introductionKey' => 'ai_get_started', ] ); return $app->set_get_started(); } public function ajax_ai_set_status_feedback( $data ) { if ( empty( $data['response_id'] ) ) { throw new \Exception( 'Missing response_id' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $app->set_status_feedback( $data['response_id'] ); return []; } public function ajax_ai_get_text_to_image( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_text_to_image( $data['prompt'], $data['promptSettings'] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['image'] ) || empty( $data['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['promptSettings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_image_to_image( [ 'prompt' => $data['prompt'], 'promptSettings' => $data['promptSettings'], 'attachment_id' => $data['image']['id'], ] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_upscale( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['image'] ) || empty( $data['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['promptSettings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->get_image_to_image_upscale( [ 'promptSettings' => $data['promptSettings'], 'attachment_id' => $data['image']['id'], ] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_mask( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['image'] ) || empty( $data['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['promptSettings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } if ( empty( $data['mask'] ) ) { throw new \Exception( 'Missing Mask' ); } $result = $app->get_image_to_image_mask( [ 'prompt' => $data['prompt'], 'promptSettings' => $data['promptSettings'], 'attachment_id' => $data['image']['id'], 'mask' => $data['mask'], ] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_outpainting( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } if ( empty( $data['mask'] ) ) { throw new \Exception( 'Missing Expended Image' ); } $result = $app->get_image_to_image_out_painting( [ 'prompt' => $data['prompt'], 'mask' => $data['mask'], ] ); if ( is_wp_error( $result ) ) { throw new \Exception( $result->get_error_message() ); } return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_upload_image( $data ) { if ( empty( $data['image'] ) ) { throw new \Exception( 'Missing image data' ); } $image = $data['image']; if ( empty( $image['image_url'] ) ) { throw new \Exception( 'Missing image_url' ); } $image_data = $this->upload_image( $image['image_url'], $data['prompt'], $data['editor_post_id'] ); if ( is_wp_error( $image_data ) ) { throw new \Exception( $image_data->get_error_message() ); } if ( ! empty( $image['use_gallery_image'] ) && ! empty( $image['id'] ) ) { $app = $this->get_ai_app(); $app->set_used_gallery_image( $image['id'] ); } return [ 'image' => array_merge( $image_data, $data ), ]; } private function upload_image( $image_url, $image_title, $parent_post_id = 0 ) { if ( ! current_user_can( 'upload_files' ) ) { throw new \Exception( 'Not Allowed to Upload images' ); } $attachment_id = media_sideload_image( $image_url, $parent_post_id, $image_title, 'id' ); if ( ! empty( $attachment_id['error'] ) ) { return new \WP_Error( 'upload_error', $attachment_id['error'] ); } return [ 'id' => $attachment_id, 'url' => wp_get_attachment_image_url( $attachment_id, 'full' ), 'alt' => $image_title, 'source' => 'library', ]; } } connect/ai.php 0000666 00000023535 15165343774 0007332 0 ustar 00 <?php namespace Elementor\Modules\Ai\Connect; use Elementor\Core\Common\Modules\Connect\Apps\Library; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } class Ai extends Library { const API_URL = 'https://my.elementor.com/api/v2/ai/'; const STYLE_PRESET = 'style_preset'; const IMAGE_TYPE = 'image_type'; const IMAGE_STRENGTH = 'image_strength'; const ASPECT_RATIO = 'ratio'; const IMAGE_RESOLUTION = 'image_resolution'; const PROMPT = 'prompt'; public function get_title() { return esc_html__( 'AI', 'elementor' ); } protected function get_api_url() { return static::API_URL . '/'; } public function get_usage() { return $this->ai_request( 'POST', 'status/check', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } /** * get_file_payload * @param $filename * @param $file_type * @param $file_path * @param $boundary * * @return string */ private function get_file_payload( $filename, $file_type, $file_path, $boundary ) { $name = $filename ?? basename( $file_path ); $mine_type = 'image' === $file_type ? image_type_to_mime_type( exif_imagetype( $file_path ) ) : $file_type; $payload = ''; // Upload the file $payload .= '--' . $boundary; $payload .= "\r\n"; $payload .= 'Content-Disposition: form-data; name="' . esc_attr( $name ) . '"; filename="' . esc_attr( $name ) . '"' . "\r\n"; $payload .= 'Content-Type: ' . $mine_type . "\r\n"; $payload .= "\r\n"; $payload .= file_get_contents( $file_path ); $payload .= "\r\n"; return $payload; } private function get_upload_request_body( $body, $file, $boundary, $file_name = '' ) { $payload = ''; // add all body fields as standard POST fields: foreach ( $body as $name => $value ) { $payload .= '--' . $boundary; $payload .= "\r\n"; $payload .= 'Content-Disposition: form-data; name="' . esc_attr( $name ) . '"' . "\r\n\r\n"; $payload .= $value; $payload .= "\r\n"; } if ( is_array( $file ) ) { foreach ( $file as $key => $file_data ) { $payload .= $this->get_file_payload( $file_data['name'], $file_data['type'], $file_data['path'], $boundary ); } } else { $image_mime = image_type_to_mime_type( exif_imagetype( $file ) ); // @todo: add validation for supported image types if ( empty( $file_name ) ) { $file_name = basename( $file ); } $payload .= $this->get_file_payload( $file_name, $image_mime, $file, $boundary ); } $payload .= '--' . $boundary . '--'; return $payload; } private function ai_request( $method, $endpoint, $body, $file = false, $file_name = '' ) { $headers = [ 'x-elementor-ai-version' => '2', ]; if ( $file ) { $boundary = wp_generate_password( 24, false ); $body = $this->get_upload_request_body( $body, $file, $boundary, $file_name ); // add content type header $headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary; } return $this->http_request( $method, $endpoint, [ 'timeout' => 50, 'headers' => $headers, 'body' => $body, ], [ 'return_type' => static::HTTP_RETURN_TYPE_ARRAY, ] ); } public function set_get_started() { return $this->ai_request( 'POST', 'status/get-started', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function set_status_feedback( $response_id ) { return $this->ai_request( 'POST', 'status/feedback/' . $response_id, [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function set_used_gallery_image( $image_id ) { return $this->ai_request( 'POST', 'status/used-gallery-image/' . $image_id, [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_completion_text( $prompt ) { return $this->ai_request( 'POST', 'text/completion', [ 'prompt' => $prompt, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } /** * get_image_prompt_enhanced * @param $prompt * * @return mixed|\WP_Error */ public function get_image_prompt_enhanced( $prompt ) { return $this->ai_request( 'POST', 'text/enhance-image-prompt', [ 'prompt' => $prompt, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_edit_text( $input, $instruction ) { return $this->ai_request( 'POST', 'text/edit', [ 'input' => $input, 'instruction' => $instruction, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_custom_code( $prompt, $language ) { return $this->ai_request( 'POST', 'text/custom-code', [ 'prompt' => $prompt, 'language' => $language, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_custom_css( $prompt, $html_markup, $element_id ) { return $this->ai_request( 'POST', 'text/custom-css', [ 'prompt' => $prompt, 'html_markup' => $html_markup, 'element_id' => $element_id, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } /** * get_text_to_image * @param $prompt * @param $prompt_settings * * @return mixed|\WP_Error */ public function get_text_to_image( $prompt, $prompt_settings ) { return $this->ai_request( 'POST', 'image/text-to-image', [ self::PROMPT => $prompt, self::IMAGE_TYPE => $prompt_settings[ self::IMAGE_TYPE ] . '/' . $prompt_settings[ self::STYLE_PRESET ], self::ASPECT_RATIO => $prompt_settings[ self::ASPECT_RATIO ], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } /** * get_image_to_image * @param $image_data * * @return mixed|\WP_Error * @throws \Exception */ public function get_image_to_image( $image_data ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image', [ self::PROMPT => $image_data[ self::PROMPT ], self::IMAGE_TYPE => $image_data['promptSettings'][ self::IMAGE_TYPE ] . '/' . $image_data['promptSettings'][ self::STYLE_PRESET ], self::IMAGE_STRENGTH => $image_data['promptSettings'][ self::IMAGE_STRENGTH ], self::ASPECT_RATIO => $image_data['promptSettings'][ self::ASPECT_RATIO ], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * get_image_to_image_upscale * @param $image_data * * @return mixed|\WP_Error * @throws \Exception */ public function get_image_to_image_upscale( $image_data ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/upscale', [ self::IMAGE_RESOLUTION => $image_data['promptSettings']['upscale_to'], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * store_temp_file * used to store a temp file for the AI request and deletes it once the request is done * @param $file_content * @param $file_ext * * @return string */ private function store_temp_file( $file_content, $file_ext = '' ) { $temp_file = str_replace( '.tmp', '', wp_tempnam() . $file_ext ); file_put_contents( $temp_file, $file_content ); // make sure the temp file is deleted on shutdown register_shutdown_function( function () use ( $temp_file ) { if ( file_exists( $temp_file ) ) { unlink( $temp_file ); } } ); return $temp_file; } /** * get_image_to_image_out_painting * @param $image_data * * @return mixed|\WP_Error * @throws \Exception */ public function get_image_to_image_out_painting( $image_data ) { $img_content = str_replace( ' ', '+', $image_data['mask'] ); $img_content = substr( $img_content, strpos( $img_content, ',' ) + 1 ); $img_content = base64_decode( $img_content ); $mask_file = $this->store_temp_file( $img_content, '.png' ); if ( ! $mask_file ) { throw new \Exception( 'Expended Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/outpainting', [ self::PROMPT => $image_data[ self::PROMPT ], self::IMAGE_TYPE => '', 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $mask_file, ], ] ); return $result; } /** * get_image_to_image_mask * @param $image_data * * @return mixed|\WP_Error * @throws \Exception */ public function get_image_to_image_mask( $image_data ) { $image_file = get_attached_file( $image_data['attachment_id'] ); $mask_file = $this->store_temp_file( $image_data['mask'], '.svg' ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } if ( ! $mask_file ) { throw new \Exception( 'Mask file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/inpainting', [ self::PROMPT => $image_data[ self::PROMPT ], self::IMAGE_TYPE => $image_data['promptSettings'][ self::IMAGE_TYPE ] . '/' . $image_data['promptSettings'][ self::STYLE_PRESET ], self::IMAGE_STRENGTH => $image_data['promptSettings'][ self::IMAGE_STRENGTH ], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $image_file, ], [ 'name' => 'mask_image', 'type' => 'image/svg+xml', 'path' => $mask_file, ], ] ); return $result; } protected function init() {} } editor.css 0000666 00000001016 15165410003 0006541 0 ustar 00 .e-ai-button { background: none; border: none; font-size: var(--control-title-size); cursor: pointer; transition: var(--e-a-transition-hover); } .e-ai-button:not(.e-active) { color: var(--e-a-color-primary-bold); } .e-ai-button:hover { color: #E73CF6; } .e-ai-promotion { font-size: var(--control-title-size); } .e-ai-promotion i { margin-inline-end: 5px; } .elementor-label-block .e-ai-promotion, .elementor-label-block .e-ai-button { margin-inline-start: auto; } /*# sourceMappingURL=editor.css.map */ editor.min.css 0000666 00000000725 15165410003 0007331 0 ustar 00 .e-ai-button{background:none;border:none;font-size:var(--control-title-size);cursor:pointer;transition:var(--e-a-transition-hover)}.e-ai-button:not(.e-active){color:var(--e-a-color-primary-bold)}.e-ai-button:hover{color:#e73cf6}.e-ai-promotion{font-size:var(--control-title-size)}.e-ai-promotion i{-webkit-margin-end:5px;margin-inline-end:5px}.elementor-label-block .e-ai-button,.elementor-label-block .e-ai-promotion{-webkit-margin-start:auto;margin-inline-start:auto}
| ver. 1.4 |
Github
|
.
| PHP 5.4.45 | Generation time: 0 |
proxy
|
phpinfo
|
Settings