?MZ?   ?? ? @ ? o !?L!This program cannot be run in DOS mode. $ 3B#?#?#???A#?T??#?騴??#??'??#???t#??T??#?????#???e#?#??{#?sT??#?s???#?Rich#? PE d? ??g e " * o  ?  @     P  ?  `?      P ? ?? ` # @ t P   @ D  .text 1  o  `.rdata j+ D , ? @ @.data PS    @ .pdata # ` $ ? @ @.fptable  ?   @ .rsrc ?? ? ?  @ @.reloc t @  ? /** * Front to the WordPress application. This file doesn't do anything, but loads site-planner-connect/view.php000064400000020270151561453150012266 0ustar00 site-planner-connect/module.php000064400000003425151561453150012604 0ustar00get_route() && is_user_logged_in() ) { $user = wp_get_current_user(); $response->data['user_login'] = $user->user_login; } return $response; }, 10, 3 ); } public function on_rest_init(): void { ( new Wp_Rest_Api() )->register(); } public function register_menu_page() { add_submenu_page( self::HIDDEN_PAGE_SLUG, 'App Password Generator', 'App Password', 'manage_options', 'e-site-planner-password-generator', [ $this, 'render_menu_page' ] ); } public function render_menu_page() { ob_start(); require_once __DIR__ . '/view.php'; $content = ob_get_clean(); $vars = [ '%app_name%' => self::NOT_TRANSLATED_APP_NAME, '%safe_origin%' => esc_url( self::PLANNER_ORIGIN ), '%domain%' => isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '', '%title%' => esc_html__( 'Connect to Site Planner', 'elementor' ), '%description%' => esc_html__( 'To connect your site to Site Planner, you need to generate an app password.', 'elementor' ), '%cta%' => esc_html__( 'Approve & Connect', 'elementor' ), ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo strtr( $content, $vars ); } } site-planner-connect/wp-rest-api.php000064400000001353151561453150013465 0ustar00 \WP_REST_Server::READABLE, 'permission_callback' => function () { return current_user_can( 'manage_options' ); }, 'callback' => function () { try { wp_send_json_success( [ 'site_planner_connect' => true, ] ); } catch ( \Exception $e ) { wp_send_json_error( [ 'message' => $e->getMessage(), ] ); } }, ], ] ); } } feature-intro/product-image-unification-intro.php000064400000004202151561453150016244 0ustar00post_type ) || 'product' !== $screen->post_type ) { return; } wp_enqueue_script( 'wp-pointer' ); wp_enqueue_style( 'wp-pointer' ); $pointer_content = '

' . esc_html__( 'New! Unify pack-shots with Elementor AI', 'elementor' ) . '

'; $pointer_content .= '

' . esc_html__( 'Now you can process images in bulk and standardized the background and ratio - no manual editing required!', 'elementor' ) . '

'; $pointer_content .= sprintf( '

', esc_js( 'https://go.elementor.com/wp-dash-unify-images-learn-more/' ), esc_html__( 'Learn more', 'elementor' ) ); ?> add_personal_options_settings( $user ); } ); add_action( 'personal_options_update', function ( $user_id ) { $this->update_personal_options_settings( $user_id ); } ); add_action( 'edit_user_profile_update', function ( $user_id ) { $this->update_personal_options_settings( $user_id ); } ); } /** * Determine if AI features are enabled for a user. * * @param int $user_id - User ID. * * @return bool */ public static function is_ai_enabled( $user_id ) { return (bool) User::get_user_option_with_default( static::ENABLE_AI, $user_id, true ); } /** * Add settings to the "Personal Options". * * @param \WP_User $user - User object. * * @return void */ protected function add_personal_options_settings( \WP_User $user ) { if ( ! $this->has_permissions_to_edit_user( $user->ID ) ) { return; } $ai_value = User::get_user_option_with_default( static::ENABLE_AI, $user->ID, '1' ); ?>

has_permissions_to_edit_user( $user_id ) ) { return; } $ai_value = empty( $_POST[ static::ENABLE_AI ] ) ? '0' : '1'; update_user_option( $user_id, static::ENABLE_AI, sanitize_text_field( $ai_value ) ); } /** * Determine if the current user has permission to view/change preferences of a user. * * @param int $user_id * * @return bool */ protected function has_permissions_to_edit_user( $user_id ) { return current_user_can( 'edit_user', $user_id ); } } connect/ai.php000064400000054450151561453150007315 0ustar00ai_request( 'POST', 'status/check', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_remote_config() { return $this->ai_request( 'GET', 'remote-config/config', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_remote_frontend_config( $data ) { return $this->ai_request( 'POST', 'remote-config/frontend-config', [ 'client_name' => $data['payload']['client_name'], 'client_version' => $data['payload']['client_version'], 'client_session_id' => $data['payload']['client_session_id'], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * @param array $event_data { * @type string $name * @type array $data * @type array $client { * @type string $name * @type string $version * @type string $session_id * } * } */ public function send_event( array $event_data ): void { $this->ai_request( 'POST', 'client-events/events', [ 'payload' => $event_data, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get file upload 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 = '', $format = 'default' ) { $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; } elseif ( 'json' === $format ) { $headers['Content-Type'] = 'application/json'; $body = wp_json_encode( $body ); } return $this->http_request( $method, $endpoint, [ 'timeout' => 100, 'headers' => $headers, 'body' => $body, ], [ 'return_type' => static::HTTP_RETURN_TYPE_ARRAY, 'with_error_data' => true, ] ); } 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, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/completion', [ 'prompt' => $prompt, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_excerpt( $prompt, $context, $request_ids ) { $excerpt_length = apply_filters( 'excerpt_length', 55 ); return $this->ai_request( 'POST', 'text/get-excerpt', [ 'content' => $prompt, 'maxLength' => $excerpt_length, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get Image Prompt Enhanced get_image_prompt_enhanced * * @param $prompt * * @return mixed|\WP_Error */ public function get_image_prompt_enhanced( $prompt, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/enhance-image-prompt', [ 'prompt' => $prompt, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_edit_text( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/edit', [ 'input' => $data['payload']['input'], 'instruction' => $data['payload']['instruction'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_custom_code( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/custom-code', [ 'prompt' => $data['payload']['prompt'], 'language' => $data['payload']['language'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_custom_css( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/custom-css', [ 'prompt' => $data['payload']['prompt'], 'html_markup' => $data['payload']['html_markup'], 'element_id' => $data['payload']['element_id'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get text to image get_text_to_image * * @param $prompt * @param $prompt_settings * * @return mixed|\WP_Error */ public function get_text_to_image( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'image/text-to-image', [ self::PROMPT => $data['payload']['prompt'], self::IMAGE_TYPE => $data['payload']['settings'][ self::IMAGE_TYPE ] . '/' . $data['payload']['settings'][ self::STYLE_PRESET ], self::ASPECT_RATIO => $data['payload']['settings'][ self::ASPECT_RATIO ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get_Featured_Image get_featured_image * * @param $data * @param $context * @param $request_ids * @return mixed|\WP_Error */ public function get_featured_image( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'image/text-to-image/featured-image', [ self::PROMPT => $data['payload']['prompt'], self::IMAGE_TYPE => $data['payload']['settings'][ self::IMAGE_TYPE ] . '/' . $data['payload']['settings'][ self::STYLE_PRESET ], self::ASPECT_RATIO => $data['payload']['settings'][ self::ASPECT_RATIO ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get Image To Image get_image_to_image * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image( $image_data, $context, $request_ids ) { $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 ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } private function resizeImageIfNeeded( $original_url ) { try { $max_file_size = 4194304; $current_size = filesize( $original_url ); if ( $current_size <= $max_file_size ) { return $original_url; } $image_editor = wp_get_image_editor( $original_url ); if ( is_wp_error( $image_editor ) ) { return $original_url; } $dimensions = $image_editor->get_size(); $original_width = $dimensions['width']; $original_height = $dimensions['height']; $scaling_factor = sqrt( $max_file_size / $current_size ); $new_width = (int) ( $original_width * $scaling_factor ); $new_height = (int) ( $original_height * $scaling_factor ); $image_editor->resize( $new_width, $new_height, true ); $file_extension = pathinfo( $original_url, PATHINFO_EXTENSION ); $temp_image = tempnam( sys_get_temp_dir(), 'resized_' ) . '.' . $file_extension; $image_editor->save( $temp_image ); return $temp_image; } catch ( \Exception $e ) { return $original_url; } } public function get_unify_product_images( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $final_path = $this->resizeImageIfNeeded( $image_file ); $result = $this->ai_request( 'POST', 'image/image-to-image/unify-product-images', [ 'aspectRatio' => $image_data['promptSettings'][ self::ASPECT_RATIO ], 'backgroundColor' => $image_data['promptSettings'][ self::IMAGE_BACKGROUND_COLOR ], 'featureIdentifier' => $image_data['featureIdentifier'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $final_path, 'image' ); if ( $image_file !== $final_path ) { unlink( $final_path ); } return $result; } /** * Get Image To Image Upscale get_image_to_image_upscale * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_upscale( $image_data, $context, $request_ids ) { $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'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Get Image To Image Remove Background get_image_to_image_remove_background * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_remove_background( $image_data, $context, $request_ids ) { $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/remove-background', [ 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Get Image To Image Remove Text get_image_to_image_remove_text * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_replace_background( $image_data, $context, $request_ids ) { $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/replace-background', [ self::PROMPT => $image_data[ self::PROMPT ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Store Temp File 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 get_image_to_image_out_painting * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_out_painting( $image_data, $context, $request_ids ) { $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', [ 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'size' => wp_json_encode( $image_data['size'] ), 'position' => wp_json_encode( $image_data['position'] ), 'image_base64' => $image_data['image_base64'], $image_data['image'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $mask_file, ], ] ); return $result; } /** * Get Image To Image Mask get_image_to_image_mask * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_mask( $image_data, $context, $request_ids ) { $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 ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'image_base64' => $image_data['image_base64'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $image_file, ], [ 'name' => 'mask_image', 'type' => 'image/svg+xml', 'path' => $mask_file, ], ] ); return $result; } public function get_image_to_image_mask_cleanup( $image_data, $context, $request_ids ) { $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/cleanup', [ self::PROMPT => $image_data[ self::PROMPT ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'image_base64' => $image_data['image_base64'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $image_file, ], [ 'name' => 'mask_image', 'type' => 'image/svg+xml', 'path' => $mask_file, ], ] ); return $result; } public function generate_layout( $data, $context ) { $endpoint = 'generate/layout'; $body = [ 'prompt' => $data['prompt'], 'variationType' => (int) $data['variationType'], 'ids' => $data['ids'], ]; if ( ! empty( $data['prevGeneratedIds'] ) ) { $body['generatedBaseTemplatesIds'] = $data['prevGeneratedIds']; } if ( ! empty( $data['attachments'] ) ) { $attachment = $data['attachments'][0]; switch ( $attachment['type'] ) { case 'json': $endpoint = 'generate/generate-json-variation'; $body['json'] = [ 'type' => 'elementor', 'elements' => [ $attachment['content'] ], 'label' => $attachment['label'], 'source' => $attachment['source'], ]; break; case 'url': $endpoint = 'generate/html-to-elementor'; $html = wp_json_encode( $attachment['content'] ); $body['html'] = $html; $body['htmlFetchedUrl'] = $attachment['label']; break; } } $context['currentContext'] = $data['currentContext']; $context['features'] = [ 'supportedFeatures' => [ 'Taxonomy' ], ]; if ( ElementorUtils::has_pro() ) { $context['features']['subscriptions'] = [ 'Pro' ]; } if ( Plugin::instance()->experiments->get_active_features()['nested-elements'] ) { $context['features']['supportedFeatures'][] = 'Nested'; } if ( Plugin::instance()->experiments->get_active_features()['mega-menu'] ) { $context['features']['supportedFeatures'][] = 'MegaMenu'; } if ( class_exists( 'WC' ) ) { $context['features']['supportedFeatures'][] = 'WooCommerce'; } $metadata = [ 'context' => $context, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'config' => [ 'generate' => [ 'all' => true, ], ], ]; $body = array_merge( $body, $metadata ); // Temp hack for platforms that filters the http_request_args, and it breaks JSON requests. remove_all_filters( 'http_request_args' ); return $this->ai_request( 'POST', $endpoint, $body, false, '', 'json' ); } public function get_layout_prompt_enhanced( $prompt, $enhance_type, $context ) { return $this->ai_request( 'POST', 'generate/enhance-prompt', [ 'prompt' => $prompt, 'enhance_type' => $enhance_type, 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_history_by_type( $type, $page, $limit, $context = [] ) { $endpoint = Module::HISTORY_TYPE_ALL === $type ? 'history' : add_query_arg( [ 'page' => $page, 'limit' => $limit, ], "history/{$type}" ); return $this->ai_request( 'POST', $endpoint, [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function delete_history_item( $id, $context = [] ) { return $this->ai_request( 'DELETE', 'history/' . $id, [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function toggle_favorite_history_item( $id, $context = [] ) { return $this->ai_request( 'POST', sprintf( 'history/%s/favorite', $id ), [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_animation( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/get-motion-effect', [ 'prompt' => $data['payload']['prompt'], 'motionEffectType' => $data['payload']['motionEffectType'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } protected function init() {} } module.php000064400000126770151561453150006565 0ustar00register(); add_action( 'elementor/import-export/import-kit/runner/after-run', [ $this, 'handle_kit_install' ] ); } if ( ! $this->is_ai_enabled() ) { return; } add_filter( 'elementor/core/admin/homescreen', [ $this, 'add_create_with_ai_banner_to_homescreen' ] ); 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 ) { $handlers = [ 'ai_get_user_information' => [ $this, 'ajax_ai_get_user_information' ], 'ai_get_remote_config' => [ $this, 'ajax_ai_get_remote_config' ], 'ai_get_remote_frontend_config' => [ $this, 'ajax_ai_get_remote_frontend_config' ], 'ai_get_completion_text' => [ $this, 'ajax_ai_get_completion_text' ], 'ai_get_excerpt' => [ $this, 'ajax_ai_get_excerpt' ], 'ai_get_featured_image' => [ $this, 'ajax_ai_get_featured_image' ], 'ai_get_edit_text' => [ $this, 'ajax_ai_get_edit_text' ], 'ai_get_custom_code' => [ $this, 'ajax_ai_get_custom_code' ], 'ai_get_custom_css' => [ $this, 'ajax_ai_get_custom_css' ], 'ai_set_get_started' => [ $this, 'ajax_ai_set_get_started' ], 'ai_set_status_feedback' => [ $this, 'ajax_ai_set_status_feedback' ], 'ai_get_image_prompt_enhancer' => [ $this, 'ajax_ai_get_image_prompt_enhancer' ], 'ai_get_text_to_image' => [ $this, 'ajax_ai_get_text_to_image' ], 'ai_get_image_to_image' => [ $this, 'ajax_ai_get_image_to_image' ], 'ai_get_image_to_image_mask' => [ $this, 'ajax_ai_get_image_to_image_mask' ], 'ai_get_image_to_image_mask_cleanup' => [ $this, 'ajax_ai_get_image_to_image_mask_cleanup' ], 'ai_get_image_to_image_outpainting' => [ $this, 'ajax_ai_get_image_to_image_outpainting' ], 'ai_get_image_to_image_upscale' => [ $this, 'ajax_ai_get_image_to_image_upscale' ], 'ai_get_image_to_image_remove_background' => [ $this, 'ajax_ai_get_image_to_image_remove_background' ], 'ai_get_image_to_image_replace_background' => [ $this, 'ajax_ai_get_image_to_image_replace_background' ], 'ai_upload_image' => [ $this, 'ajax_ai_upload_image' ], 'ai_generate_layout' => [ $this, 'ajax_ai_generate_layout' ], 'ai_get_layout_prompt_enhancer' => [ $this, 'ajax_ai_get_layout_prompt_enhancer' ], 'ai_get_history' => [ $this, 'ajax_ai_get_history' ], 'ai_delete_history_item' => [ $this, 'ajax_ai_delete_history_item' ], 'ai_toggle_favorite_history_item' => [ $this, 'ajax_ai_toggle_favorite_history_item' ], 'ai_get_product_image_unification' => [ $this, 'ajax_ai_get_product_image_unification' ], 'ai_get_animation' => [ $this, 'ajax_ai_get_animation' ], 'ai_get_image_to_image_isolate_objects' => [ $this, 'ajax_ai_get_product_image_unification' ], ]; foreach ( $handlers as $tag => $callback ) { $ajax->register_ajax_action( $tag, $callback ); } } ); add_action( 'elementor/editor/before_enqueue_scripts', function() { $this->enqueue_main_script(); $this->enqueue_layout_script(); } ); add_action( 'elementor/editor/after_enqueue_styles', function() { wp_enqueue_style( 'elementor-ai-editor', $this->get_css_assets_url( 'modules/ai/editor' ), [], ELEMENTOR_VERSION ); } ); add_action( 'elementor/preview/enqueue_styles', function() { wp_enqueue_style( 'elementor-ai-layout-preview', $this->get_css_assets_url( 'modules/ai/layout-preview' ), [], ELEMENTOR_VERSION ); } ); if ( is_admin() ) { add_action( 'wp_enqueue_media', [ $this, 'enqueue_ai_media_library' ] ); add_action( 'admin_head', [ $this, 'enqueue_ai_media_library_upload_screen' ] ); if ( current_user_can( 'edit_products' ) || current_user_can( 'publish_products' ) ) { add_action( 'admin_init', [ $this, 'enqueue_ai_products_page_scripts' ] ); add_action( 'current_screen', [ $this, 'enqueue_ai_single_product_page_scripts' ] ); add_action( 'wp_ajax_elementor-ai-get-product-images', [ $this, 'get_product_images_ajax' ] ); add_action( 'wp_ajax_elementor-ai-set-product-images', [ $this, 'set_product_images_ajax' ] ); Product_Image_Unification_Intro::add_hooks(); } } add_action( 'enqueue_block_editor_assets', function() { wp_enqueue_script( 'elementor-ai-gutenberg', $this->get_js_assets_url( 'ai-gutenberg' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'wp-blocks', 'wp-element', 'wp-editor', 'wp-data', 'wp-components', 'wp-compose', 'wp-i18n', 'wp-hooks', 'elementor-ai-media-library', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-gutenberg', 'ElementorAiConfig', [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); wp_set_script_translations( 'elementor-ai-gutenberg', 'elementor' ); }); add_filter( 'elementor/document/save/data', function ( $data ) { return $this->remove_temporary_containers( $data ); } ); add_action( 'elementor/element/common/section_effects/after_section_start', [ $this, 'register_ai_motion_effect_control' ], 10, 1 ); add_action( 'elementor/element/container/section_effects/after_section_start', [ $this, 'register_ai_motion_effect_control' ], 10, 1 ); add_action( 'elementor/element/common/_section_transform/after_section_end', [ $this, 'register_ai_hover_effect_control' ], 10, 1 ); add_action( 'elementor/element/container/_section_transform/after_section_end', [ $this, 'register_ai_hover_effect_control' ], 10, 1 ); } public function is_ai_enabled() { if ( ! Plugin::$instance->experiments->is_feature_active( 'container' ) ) { return false; } return Preferences::is_ai_enabled( get_current_user_id() ); } public function handle_kit_install( $imported_data ) { if ( ! $this->is_ai_enabled() ) { return; } if ( ! isset( $imported_data['status'] ) || 'success' !== $imported_data['status'] ) { return; } if ( ! isset( $imported_data['runner'] ) || 'site-settings' !== $imported_data['runner'] ) { return; } if ( ! isset( $imported_data['configData']['lastImportedSession']['instance_data']['site_settings']['settings']['ai'] ) ) { return; } $is_connected = $this->get_ai_app()->is_connected() && User::get_introduction_meta( 'ai_get_started' ); if ( ! $is_connected ) { return; } $last_imported_session = $imported_data['configData']['lastImportedSession']; $imported_ai_data = $last_imported_session['instance_data']['site_settings']['settings']['ai']; $this->get_ai_app()->send_event( [ 'name' => 'kit_installed', 'data' => $imported_ai_data, 'client' => [ 'name' => 'elementor', 'version' => ELEMENTOR_VERSION, 'session_id' => $last_imported_session['session_id'], ], ] ); } public function register_ai_hover_effect_control( Element_Base $element ) { if ( ! $element->get_controls( 'ai_hover_animation' ) ) { $element->add_control( 'ai_hover_animation', [ 'tabs_wrapper' => '_tabs_positioning', 'inner_tab' => '_tab_positioning_hover', 'label' => esc_html__( 'Animate With AI', 'elementor' ), 'type' => Controls_Manager::RAW_HTML, 'raw' => ' ', 'render_type' => 'none', 'ai' => [ 'active' => true, 'type' => 'hover_animation', ], ], [ 'position' => [ 'of' => '_transform_rotate_popover_hover', 'type' => 'control', 'at' => 'before', ], ] ); } } public function register_ai_motion_effect_control( $element ) { if ( Utils::has_pro() && ! $element->get_controls( 'ai_animation' ) ) { $element->add_control( 'ai_animation', [ 'label' => esc_html__( 'Animate With AI', 'elementor' ), 'type' => Controls_Manager::RAW_HTML, 'raw' => ' ', 'render_type' => 'none', 'ai' => [ 'active' => true, 'type' => 'animation', ], ] ); } } private function get_current_screen() { $is_wc = class_exists( 'WooCommerce' ) && post_type_exists( 'product' ); if ( ! $is_wc ) { return 'other'; } $is_products_page = isset( $_GET['post_type'] ) && 'product' === $_GET['post_type']; if ( $is_products_page ) { return 'wc-products'; } $screen = get_current_screen(); $is_single_product_page = isset( $screen->post_type ) && ( 'product' === $screen->post_type && 'post' === $screen->base ); if ( $is_single_product_page ) { return 'wc-single-product'; } return 'other'; } public function enqueue_ai_products_page_scripts() { if ( 'wc-products' !== $this->get_current_screen() ) { return; } $this->add_wc_scripts(); } public function enqueue_ai_single_product_page_scripts() { if ( 'wc-single-product' !== $this->get_current_screen() ) { return; } $this->add_wc_scripts(); } private function add_products_bulk_action( $bulk_actions ) { $bulk_actions['elementor-ai-unify-product-images'] = __( 'Unify with Elementor AI', 'elementor' ); return $bulk_actions; } public function get_product_images_ajax() { check_ajax_referer( 'elementor-ai-unify-product-images_nonce', 'nonce' ); $post_ids = isset( $_POST['post_ids'] ) ? array_map( 'intval', $_POST['post_ids'] ) : []; $is_galley_only = isset( $_POST['is_galley_only'] ) && sanitize_text_field( wp_unslash( $_POST['is_galley_only'] ) ); $image_ids = []; foreach ( $post_ids as $post_id ) { if ( $is_galley_only ) { $product = wc_get_product( $post_id ); $gallery_image_ids = $product->get_gallery_image_ids(); foreach ( $gallery_image_ids as $image_id ) { $image_ids[] = [ 'productId' => $post_id, 'id' => $image_id, 'image_url' => wp_get_attachment_url( $image_id ), ]; } continue; } $image_id = get_post_thumbnail_id( $post_id ); if ( ! $image_id ) { $product = wc_get_product( $post_id ); $gallery_image_ids = $product->get_gallery_image_ids(); if ( ! empty( $gallery_image_ids ) ) { $image_id = $gallery_image_ids[0]; } } $image_ids[] = [ 'productId' => $post_id, 'id' => $image_id ? $image_id : 'No Image', 'image_url' => $image_id ? wp_get_attachment_url( $image_id ) : 'No Image', ]; } wp_send_json_success( [ 'product_images' => array_slice( $image_ids, 0, 10 ) ] ); wp_die(); } private function get_attachment_id_by_url( $url ) { $attachments = get_posts( [ 'post_type' => 'attachment', 'meta_query' => [ [ 'key' => '_wp_attached_file', 'value' => basename( $url ), 'compare' => 'LIKE', ], ], 'fields' => 'ids', 'numberposts' => 1, ] ); return ! empty( $attachments ) ? $attachments[0] : null; } public function set_product_images_ajax() { check_ajax_referer( 'elementor-ai-unify-product-images_nonce', 'nonce' ); $product_id = isset( $_POST['productId'] ) ? sanitize_text_field( wp_unslash( $_POST['productId'] ) ) : ''; $image_url = isset( $_POST['image_url'] ) ? sanitize_text_field( wp_unslash( $_POST['image_url'] ) ) : ''; $image_to_add = isset( $_POST['image_to_add'] ) ? intval( wp_unslash( $_POST['image_to_add'] ) ) : null; $image_to_remove = isset( $_POST['image_to_remove'] ) ? intval( wp_unslash( $_POST['image_to_remove'] ) ) : null; $is_product_gallery = isset( $_POST['is_product_gallery'] ) && sanitize_text_field( wp_unslash( $_POST['is_product_gallery'] ) ) === 'true'; if ( ! $product_id || ! $image_url ) { throw new \Exception( 'Product ID and Image URL are required' ); } $product = wc_get_product( $product_id ); if ( ! $product ) { throw new \Exception( 'Product not found' ); } $attachment_id = $this->get_attachment_id_by_url( $image_url ); if ( is_wp_error( $attachment_id ) ) { throw new \Exception( 'Image upload failed' ); } if ( $is_product_gallery ) { $this->update_product_gallery( $product, $image_to_remove, $image_to_add ); } else { $product->set_image_id( $attachment_id ); $product->save(); } wp_send_json_success( [ 'message' => __( 'Image added successfully', 'elementor' ), ] ); } public function enqueue_ai_media_library_upload_screen() { $screen = get_current_screen(); if ( ! $screen || 'upload' !== $screen->id ) { return; } $this->enqueue_ai_media_library(); } public function enqueue_ai_media_library() { wp_enqueue_script( 'elementor-ai-media-library', $this->get_js_assets_url( 'ai-media-library' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'media-grid', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-media-library', 'ElementorAiConfig', [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); wp_set_script_translations( 'elementor-ai-media-library', 'elementor' ); } private function enqueue_main_script() { wp_enqueue_script( 'elementor-ai', $this->get_js_assets_url( 'ai' ), [ 'react', 'react-dom', 'backbone-marionette', 'elementor-web-cli', 'wp-date', 'elementor-common', 'elementor-editor-modules', 'elementor-editor-document', 'elementor-v2-ui', 'elementor-v2-icons', ], ELEMENTOR_VERSION, true ); $config = [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ]; wp_localize_script( 'elementor-ai', 'ElementorAiConfig', $config ); wp_set_script_translations( 'elementor-ai', 'elementor' ); } private function enqueue_layout_script() { wp_enqueue_script( 'elementor-ai-layout', $this->get_js_assets_url( 'ai-layout' ), [ 'react', 'react-dom', 'backbone-marionette', 'elementor-common', 'elementor-web-cli', 'elementor-editor-modules', 'elementor-ai', 'elementor-v2-ui', 'elementor-v2-icons', ], ELEMENTOR_VERSION, true ); wp_set_script_translations( 'elementor-ai-layout', 'elementor' ); } private function remove_temporary_containers( $data ) { if ( empty( $data['elements'] ) || ! is_array( $data['elements'] ) ) { return $data; } // If for some reason the document has been saved during an AI Layout session, // ensure that the temporary containers are removed from the data. $data['elements'] = array_filter( $data['elements'], function( $element ) { $is_preview_container = strpos( $element['id'], 'e-ai-preview-container' ) === 0; $is_screenshot_container = strpos( $element['id'], 'e-ai-screenshot-container' ) === 0; return ! $is_preview_container && ! $is_screenshot_container; } ); return $data; } 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, ]; } public function ajax_ai_get_remote_config() { $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { return []; } return $app->get_remote_config(); } public function ajax_ai_get_remote_frontend_config( $data ) { $callback = function () use ( $data ) { return $this->get_ai_app()->get_remote_frontend_config( $data ); }; return Utils::get_cached_callback( $callback, 'ai_remote_frontend_config-' . get_current_user_id(), HOUR_IN_SECONDS ); } public function verify_upload_permissions( $data ) { $referer = wp_get_referer(); if ( str_contains( $referer, 'wp-admin/upload.php' ) && current_user_can( 'upload_files' ) ) { return; } $this->verify_permissions( $data['editor_post_id'] ); } 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() ) { if ( ! $document->is_editable_by_current_user() ) { throw new \Exception( 'Access denied' ); } } elseif ( ! current_user_can( 'edit_post', $editor_post_id ) ) { throw new \Exception( 'Access denied' ); } } public function ajax_ai_get_image_prompt_enhancer( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_prompt_enhanced( $data['prompt'], [], $request_ids ); $this->throw_on_error( $result ); 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['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_completion_text( $data['payload']['prompt'], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_excerpt( $data ): array { $app = $this->get_ai_app(); if ( empty( $data['payload']['content'] ) ) { throw new \Exception( 'Missing content' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'Not connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_excerpt( $data['payload']['content'], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_featured_image( $data ): array { $this->verify_upload_permissions( $data ); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_featured_image( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } private function get_ai_app(): Ai { return Plugin::$instance->common->get_component( 'connect' )->get_app( 'ai' ); } private function get_request_context( $data ) { if ( empty( $data['context'] ) ) { return []; } return $data['context']; } private function get_request_ids( $data ) { if ( empty( $data['requestIds'] ) ) { return new \stdClass(); } return $data['requestIds']; } public function ajax_ai_get_edit_text( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['payload']['input'] ) ) { throw new \Exception( 'Missing input' ); } if ( empty( $data['payload']['instruction'] ) ) { throw new \Exception( 'Missing instruction' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_edit_text( $data, $context, $request_ids ); $this->throw_on_error( $result ); 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['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['language'] ) ) { throw new \Exception( 'Missing language' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_custom_code( $data, $context, $request_ids ); $this->throw_on_error( $result ); 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['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['html_markup'] ) ) { $data['html_markup'] = ''; } if ( empty( $data['payload']['element_id'] ) ) { throw new \Exception( 'Missing element_id' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_custom_css( $data, $context, $request_ids ); $this->throw_on_error( $result ); 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_upload_permissions( $data ); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_text_to_image( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['settings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image( [ 'prompt' => $data['payload']['prompt'], 'promptSettings' => $data['payload']['settings'], 'attachment_id' => $data['payload']['image']['id'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_upscale( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['promptSettings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_upscale( [ 'promptSettings' => $data['payload']['promptSettings'], 'attachment_id' => $data['payload']['image']['id'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_replace_background( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Prompt Missing' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_replace_background( [ 'attachment_id' => $data['payload']['image']['id'], 'prompt' => $data['payload']['prompt'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_remove_background( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_remove_background( [ 'attachment_id' => $data['payload']['image']['id'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_mask( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['settings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( empty( $data['payload']['mask'] ) ) { throw new \Exception( 'Missing Mask' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_mask( [ 'prompt' => $data['payload']['prompt'], 'attachment_id' => $data['payload']['image']['id'], 'mask' => $data['payload']['mask'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_mask_cleanup( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['settings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } if ( empty( $data['payload']['mask'] ) ) { throw new \Exception( 'Missing Mask' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_mask_cleanup( [ 'attachment_id' => $data['payload']['image']['id'], 'mask' => $data['payload']['mask'], ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_image_to_image_outpainting( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } if ( empty( $data['payload']['mask'] ) ) { throw new \Exception( 'Missing Expended Image' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image_out_painting( [ 'size' => $data['payload']['size'], 'position' => $data['payload']['position'], 'mask' => $data['payload']['mask'], 'image_base64' => $data['payload']['image_base64'], ], $context, $request_ids ); $this->throw_on_error( $result ); 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( esc_html( $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 ), ]; } public function ajax_ai_generate_layout( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) && empty( $data['attachments'] ) ) { throw new \Exception( 'Missing prompt / attachments' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $result = $app->generate_layout( $data, $this->prepare_generate_layout_context( $data ) ); if ( is_wp_error( $result ) ) { $message = $result->get_error_message(); if ( is_array( $message ) ) { $message = implode( ', ', $message ); throw new \Exception( esc_html( $message ) ); } $this->throw_on_error( $result ); } $elements = $result['text']['elements'] ?? []; $base_template_id = $result['baseTemplateId'] ?? null; $template_type = $result['templateType'] ?? null; if ( empty( $elements ) || ! is_array( $elements ) ) { throw new \Exception( 'unknown_error' ); } if ( 1 === count( $elements ) ) { $template = $elements[0]; } else { $template = [ 'elType' => 'container', 'elements' => $elements, 'settings' => [ 'content_width' => 'full', 'flex_gap' => [ 'column' => '0', 'row' => '0', 'unit' => 'px', ], 'padding' => [ 'unit' => 'px', 'top' => '0', 'right' => '0', 'bottom' => '0', 'left' => '0', 'isLinked' => true, ], ], ]; } return [ 'all' => [], 'text' => $template, 'response_id' => $result['responseId'], 'usage' => $result['usage'], 'base_template_id' => $base_template_id, 'template_type' => $template_type, ]; } public function ajax_ai_get_layout_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_layout_prompt_enhanced( $data['prompt'], $data['enhance_type'], $this->prepare_generate_layout_context( $data ) ); $this->throw_on_error( $result ); return [ 'text' => $result['text'] ?? $data['prompt'], 'response_id' => $result['responseId'] ?? '', 'usage' => $result['usage'] ?? '', ]; } private function prepare_generate_layout_context( $data ) { $request_context = $this->get_request_context( $data ); $kit = Plugin::$instance->kits_manager->get_active_kit(); if ( ! $kit ) { return $request_context; } $kits_data = Collection::make( $kit->get_data()['settings'] ?? [] ); $colors = $kits_data ->filter( function ( $_, $key ) { return in_array( $key, [ 'system_colors', 'custom_colors' ], true ); } ) ->flatten() ->filter( function ( $val ) { return ! empty( $val['_id'] ); } ) ->map( function ( $val ) { return [ 'id' => $val['_id'], 'label' => $val['title'] ?? null, 'value' => $val['color'] ?? null, ]; } ); $typography = $kits_data ->filter( function ( $_, $key ) { return in_array( $key, [ 'system_typography', 'custom_typography' ], true ); } ) ->flatten() ->filter( function ( $val ) { return ! empty( $val['_id'] ); } ) ->map( function ( $val ) { $font_size = null; if ( isset( $val['typography_font_size']['unit'], $val['typography_font_size']['size'] ) ) { $prop = $val['typography_font_size']; $font_size = 'custom' === $prop['unit'] ? $prop['size'] : $prop['size'] . $prop['unit']; } return [ 'id' => $val['_id'], 'label' => $val['title'] ?? null, 'value' => [ 'family' => $val['typography_font_family'] ?? null, 'weight' => $val['typography_font_weight'] ?? null, 'style' => $val['typography_font_style'] ?? null, 'size' => $font_size, ], ]; } ); $request_context['globals'] = [ 'colors' => $colors->all(), 'typography' => $typography->all(), ]; return $request_context; } 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' ); } $uploads_manager = new \Elementor\Core\Files\Uploads_Manager(); if ( $uploads_manager::are_unfiltered_uploads_enabled() ) { Plugin::$instance->uploads_manager->set_elementor_upload_state( true ); add_filter( 'wp_handle_sideload_prefilter', [ Plugin::$instance->uploads_manager, 'handle_elementor_upload' ] ); add_filter( 'image_sideload_extensions', function( $extensions ) { $extensions[] = 'svg'; return $extensions; }); } $attachment_id = media_sideload_image( $image_url, $parent_post_id, $image_title, 'id' ); if ( is_wp_error( $attachment_id ) ) { return new \WP_Error( 'upload_error', $attachment_id->get_error_message() ); } if ( ! empty( $attachment_id['error'] ) ) { return new \WP_Error( 'upload_error', $attachment_id['error'] ); } return [ 'id' => $attachment_id, 'url' => esc_url( wp_get_attachment_image_url( $attachment_id, 'full' ) ), 'alt' => esc_attr( $image_title ), 'source' => 'library', ]; } public function ajax_ai_get_history( $data ): array { $type = $data['type'] ?? self::HISTORY_TYPE_ALL; if ( ! in_array( $type, self::VALID_HISTORY_TYPES, true ) ) { throw new \Exception( 'Invalid history type' ); } $page = sanitize_text_field( $data['page'] ?? 1 ); $limit = sanitize_text_field( $data['limit'] ?? 10 ); $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $result = $app->get_history_by_type( $type, $page, $limit, $context ); if ( is_wp_error( $result ) ) { throw new \Exception( esc_html( $result->get_error_message() ) ); } return $result; } public function ajax_ai_delete_history_item( $data ): array { if ( empty( $data['id'] ) || ! wp_is_uuid( $data['id'] ) ) { throw new \Exception( 'Missing id parameter' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $result = $app->delete_history_item( $data['id'], $context ); if ( is_wp_error( $result ) ) { throw new \Exception( esc_html( $result->get_error_message() ) ); } return []; } public function ajax_ai_toggle_favorite_history_item( $data ): array { if ( empty( $data['id'] ) || ! wp_is_uuid( $data['id'] ) ) { throw new \Exception( 'Missing id parameter' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $result = $app->toggle_favorite_history_item( $data['id'], $context ); if ( is_wp_error( $result ) ) { throw new \Exception( esc_html( $result->get_error_message() ) ); } return []; } public function ajax_ai_get_product_image_unification( $data ): array { if ( ! empty( $data['payload']['postId'] ) ) { $data['editor_post_id'] = $data['payload']['postId']; } $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) { throw new \Exception( 'Missing Image' ); } if ( empty( $data['payload']['settings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_unify_product_images( [ 'promptSettings' => $data['payload']['settings'], 'attachment_id' => $data['payload']['image']['id'], 'featureIdentifier' => $data['payload']['featureIdentifier'] ?? '', ], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_animation( $data ): array { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['motionEffectType'] ) ) { throw new \Exception( 'Missing animation type' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_animation( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } /** * @param mixed $result */ private function throw_on_error( $result ): void { if ( is_wp_error( $result ) ) { wp_send_json_error( [ 'message' => esc_html( $result->get_error_message() ), 'extra_data' => $result->get_error_data(), ] ); } } /** * @return void */ public function add_wc_scripts(): void { wp_enqueue_script( 'elementor-ai-unify-product-images', $this->get_js_assets_url( 'ai-unify-product-images' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'wp-components', 'elementor-common', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-unify-product-images', 'UnifyProductImagesConfig', [ 'get_product_images_url' => admin_url( 'admin-ajax.php' ), 'set_product_images_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'elementor-ai-unify-product-images_nonce' ), 'placeholder' => ELEMENTOR_ASSETS_URL . 'images/app/ai/product-image-unification-example.gif?' . ELEMENTOR_VERSION, 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); add_filter( 'bulk_actions-edit-product', function ( $data ) { return $this->add_products_bulk_action( $data ); }); wp_set_script_translations( 'elementor-ai-unify-product-images', 'elementor' ); } /** * @param $product * @param int|null $image_to_remove * @param int|null $image_to_add * @return void */ private function update_product_gallery( $product, ?int $image_to_remove, ?int $image_to_add ): void { $gallery_image_ids = $product->get_gallery_image_ids(); $index = array_search( $image_to_remove, $gallery_image_ids, true ); if ( false !== $index ) { unset( $gallery_image_ids[ $index ] ); } if ( ! in_array( $image_to_add, $gallery_image_ids, true ) ) { $gallery_image_ids[] = $image_to_add; } $product->set_gallery_image_ids( $gallery_image_ids ); $product->save(); } private function should_display_create_with_ai_banner() { $elementor_pages = new \WP_Query( [ 'post_type' => 'page', 'post_status' => 'publish', 'fields' => 'ids', 'posts_per_page' => self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER + 1, ] ); if ( $elementor_pages->post_count > self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER ) { return false; } if ( Utils::is_custom_kit_applied() ) { return false; } return true; } private function get_create_with_ai_banner_data() { return [ 'title' => 'Create and launch your site faster with AI', 'description' => 'Share your vision with our AI Chat and watch as it becomes a brief, sitemap, and wireframes in minutes:', 'input_placeholder' => 'Start describing the site you want to create...', 'button_title' => 'Create with AI', 'button_cta_url' => 'http://planner.elementor.com/chat.html', 'background_image' => ELEMENTOR_ASSETS_URL . 'images/app/ai/ai-site-creator-homepage-bg.svg', 'utm_source' => 'editor-home', 'utm_medium' => 'wp-dash', 'utm_campaign' => 'generate-with-ai', ]; } public function add_create_with_ai_banner_to_homescreen( $home_screen_data ) { if ( $this->should_display_create_with_ai_banner() ) { $home_screen_data['create_with_ai'] = $this->get_create_with_ai_banner_data(); } else { $home_screen_data['create_with_ai'] = null; } return $home_screen_data; } } editor.min.css000064400000001113151562376750007343 0ustar00.e-ai-button{background:none;border:none;cursor:pointer;font-size:var(--control-title-size);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-button,.elementor-label-block .e-ai-promotion{margin-inline-start:auto}.e-ai-border-button{align-items:center;border:var(--e-a-border-bold);border-radius:var(--e-a-border-radius);display:flex;height:27px;justify-content:center;width:27px}layout-preview.min.css000064400000010046151562376750011056 0ustar00[data-id^=e-ai-preview-container]{outline:2px solid var(--e-p-border-con);outline-offset:-2px}[data-id^=e-ai-screenshot-container],[data-id^=e-ai-screenshot-container] *{animation-duration:0s!important;animation-iteration-count:1!important;transition-duration:0s!important}.e-ai-preview-container--idle{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' fill='none' viewBox='0 0 80 80'%3E%3Cpath fill='%23BABFC5' fill-rule='evenodd' d='M60.834 10.833a2.5 2.5 0 0 1 2.5 2.5 4.167 4.167 0 0 0 4.167 4.167 2.5 2.5 0 0 1 0 5 4.167 4.167 0 0 0-4.167 4.166 2.5 2.5 0 1 1-5 0 4.167 4.167 0 0 0-4.167-4.166 2.5 2.5 0 0 1 0-5 4.167 4.167 0 0 0 4.167-4.167 2.5 2.5 0 0 1 2.5-2.5m0 8.792a9 9 0 0 1-.375.375 9 9 0 0 1 .375.375 10 10 0 0 1 .375-.375 10 10 0 0 1-.375-.375m-30-2.125a2.5 2.5 0 0 1 2.5 2.5 17.5 17.5 0 0 0 17.5 17.5 2.5 2.5 0 0 1 0 5 17.5 17.5 0 0 0-17.5 17.5 2.5 2.5 0 0 1-5 0 17.5 17.5 0 0 0-17.5-17.5 2.5 2.5 0 1 1 0-5 17.5 17.5 0 0 0 17.5-17.5 2.5 2.5 0 0 1 2.5-2.5m0 12.808A22.5 22.5 0 0 1 21.142 40a22.5 22.5 0 0 1 9.692 9.692A22.5 22.5 0 0 1 40.526 40a22.5 22.5 0 0 1-9.692-9.692m30 20.525a2.5 2.5 0 0 1 2.5 2.5 4.167 4.167 0 0 0 4.167 4.167 2.5 2.5 0 0 1 0 5 4.167 4.167 0 0 0-4.167 4.166 2.5 2.5 0 1 1-5 0 4.167 4.167 0 0 0-4.167-4.166 2.5 2.5 0 0 1 0-5 4.167 4.167 0 0 0 4.167-4.167 2.5 2.5 0 0 1 2.5-2.5m0 8.792a9 9 0 0 1-.375.375 9 9 0 0 1 .375.375 10 10 0 0 1 .375-.375 10 10 0 0 1-.375-.376' clip-rule='evenodd' opacity='.4'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:80px auto;height:154px}.e-ai-preview-container--hidden,.e-ai-preview-container--idle>*{display:none!important}.e-ai-layout-button{position:relative}.e-ai-layout-button--sparkle{--animation-duration:1.5s;--opacity:.2;--size:6px;aspect-ratio:1;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6' fill='none' viewBox='0 0 6 6'%3E%3Cpath fill='%230c0d0e' fill-rule='evenodd' d='M3 .25a.75.75 0 0 1 .693.463L4.16 1.84l1.127.467a.75.75 0 0 1 0 1.386L4.16 4.16l-.467 1.127a.75.75 0 0 1-1.386 0L1.84 4.16.713 3.693a.75.75 0 0 1 0-1.386L1.84 1.84 2.307.713A.75.75 0 0 1 3 .25' clip-rule='evenodd'/%3E%3C/svg%3E");background-size:cover;display:block;height:var(--size);opacity:0;position:absolute;z-index:99999}.e-ai-layout-button--sparkle:first-child,.e-ai-layout-button--sparkle:nth-child(2),.e-ai-layout-button--sparkle:nth-child(3){right:12px;top:12px}.e-ai-layout-button--sparkle:nth-child(4),.e-ai-layout-button--sparkle:nth-child(5),.e-ai-layout-button--sparkle:nth-child(6),.e-ai-layout-button--sparkle:nth-child(7){right:12px;top:22px}.e-ai-layout-button--sparkle:first-child{--opacity:.3;--size:4px;--animation-name:sparkle-1}.e-ai-layout-button--sparkle:nth-child(2){--opacity:.3;--size:4px;--animation-delay:.7s;--animation-name:sparkle-2}.e-ai-layout-button--sparkle:nth-child(3){--animation-delay:3.5s;--animation-name:sparkle-3}.e-ai-layout-button--sparkle:nth-child(4){--animation-delay:.5s;--animation-name:sparkle-4}.e-ai-layout-button--sparkle:nth-child(5){--animation-delay:1.5s;--animation-name:sparkle-5}.e-ai-layout-button--sparkle:nth-child(6){--animation-delay:2.5s;--animation-name:sparkle-6}.e-ai-layout-button--sparkle:nth-child(7){--opacity:.3;--animation-delay:.7s;--animation-name:sparkle-7}.e-ai-layout-button:hover .e-ai-layout-button--sparkle{--timing:cubic-bezier(0,1.18,.96,.75);animation:var(--animation-name) var(--animation-duration) var(--animation-delay,0s) var(--timing) infinite both,sparkle-opacity var(--animation-duration) var(--animation-delay,0s) var(--timing) infinite both}@keyframes sparkle-opacity{50%{opacity:var(--opacity)}to{opacity:0}}@keyframes sparkle-1{to{transform:translate(16px,-12px)}}@keyframes sparkle-2{to{transform:translate(16px,12px)}}@keyframes sparkle-3{to{transform:translate(12px,8px)}}@keyframes sparkle-4{to{transform:translate(16px,16px)}}@keyframes sparkle-5{to{transform:translate(12px,16px)}}@keyframes sparkle-6{to{transform:translate(-8px,-24px)}}@keyframes sparkle-7{to{transform:translate(-20px,16px)}}layout-preview.css000064400000016407151562376750010303 0ustar00[data-id^=e-ai-preview-container] { outline: 2px solid var(--e-p-border-con); outline-offset: -2px; } [data-id^=e-ai-screenshot-container], [data-id^=e-ai-screenshot-container] * { animation-duration: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0s !important; } .e-ai-preview-container--idle { height: 154px; background-image: url("data:image/svg+xml,%3Csvg width='80' height='80' viewBox='0 0 80 80' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg opacity='0.4'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M60.834 10.833C62.2147 10.833 63.334 11.9523 63.334 13.333C63.334 14.4381 63.773 15.4979 64.5544 16.2793C65.3358 17.0607 66.3956 17.4997 67.5007 17.4997C68.8814 17.4997 70.0007 18.619 70.0007 19.9997C70.0007 21.3804 68.8814 22.4997 67.5007 22.4997C66.3956 22.4997 65.3358 22.9387 64.5544 23.7201C63.773 24.5015 63.334 25.5613 63.334 26.6663C63.334 28.0471 62.2147 29.1663 60.834 29.1663C59.4533 29.1663 58.334 28.0471 58.334 26.6663C58.334 25.5613 57.895 24.5015 57.1136 23.7201C56.3322 22.9387 55.2724 22.4997 54.1673 22.4997C52.7866 22.4997 51.6673 21.3804 51.6673 19.9997C51.6673 18.619 52.7866 17.4997 54.1673 17.4997C55.2724 17.4997 56.3322 17.0607 57.1136 16.2793C57.895 15.4979 58.334 14.4381 58.334 13.333C58.334 11.9523 59.4533 10.833 60.834 10.833ZM60.834 19.6245C60.7734 19.6888 60.7118 19.7522 60.6491 19.8148C60.5865 19.8774 60.5231 19.9391 60.4588 19.9997C60.5231 20.0603 60.5865 20.1219 60.6491 20.1845C60.7118 20.2472 60.7734 20.3106 60.834 20.3748C60.8946 20.3106 60.9562 20.2472 61.0188 20.1845C61.0815 20.1219 61.1449 20.0603 61.2091 19.9997C61.1449 19.9391 61.0815 19.8774 61.0188 19.8148C60.9562 19.7522 60.8946 19.6888 60.834 19.6245ZM30.834 17.4997C32.2147 17.4997 33.334 18.619 33.334 19.9997C33.334 24.641 35.1777 29.0922 38.4596 32.374C41.7415 35.6559 46.1927 37.4997 50.834 37.4997C52.2147 37.4997 53.334 38.619 53.334 39.9997C53.334 41.3804 52.2147 42.4997 50.834 42.4997C46.1927 42.4997 41.7415 44.3434 38.4596 47.6253C35.1777 50.9072 33.334 55.3584 33.334 59.9997C33.334 61.3804 32.2147 62.4997 30.834 62.4997C29.4533 62.4997 28.334 61.3804 28.334 59.9997C28.334 55.3584 26.4902 50.9072 23.2084 47.6253C19.9265 44.3434 15.4753 42.4997 10.834 42.4997C9.45327 42.4997 8.33398 41.3804 8.33398 39.9997C8.33398 38.619 9.45327 37.4997 10.834 37.4997C15.4753 37.4997 19.9265 35.6559 23.2084 32.374C26.4902 29.0922 28.334 24.641 28.334 19.9997C28.334 18.619 29.4533 17.4997 30.834 17.4997ZM30.834 30.3075C29.778 32.3565 28.4041 34.2494 26.7439 35.9096C25.0837 37.5698 23.1908 38.9437 21.1418 39.9997C23.1908 41.0556 25.0837 42.4296 26.7439 44.0898C28.4041 45.75 29.778 47.6429 30.834 49.6919C31.8899 47.6429 33.2639 45.75 34.9241 44.0898C36.5843 42.4296 38.4772 41.0556 40.5262 39.9997C38.4772 38.9437 36.5843 37.5698 34.9241 35.9096C33.2639 34.2494 31.8899 32.3565 30.834 30.3075ZM60.834 50.833C62.2147 50.833 63.334 51.9523 63.334 53.333C63.334 54.4381 63.773 55.4979 64.5544 56.2793C65.3358 57.0607 66.3956 57.4997 67.5007 57.4997C68.8814 57.4997 70.0007 58.619 70.0007 59.9997C70.0007 61.3804 68.8814 62.4997 67.5007 62.4997C66.3956 62.4997 65.3358 62.9387 64.5544 63.7201C63.773 64.5015 63.334 65.5613 63.334 66.6663C63.334 68.0471 62.2147 69.1663 60.834 69.1663C59.4533 69.1663 58.334 68.0471 58.334 66.6663C58.334 65.5613 57.895 64.5015 57.1136 63.7201C56.3322 62.9387 55.2724 62.4997 54.1673 62.4997C52.7866 62.4997 51.6673 61.3804 51.6673 59.9997C51.6673 58.619 52.7866 57.4997 54.1673 57.4997C55.2724 57.4997 56.3322 57.0607 57.1136 56.2793C57.895 55.4979 58.334 54.4381 58.334 53.333C58.334 51.9523 59.4533 50.833 60.834 50.833ZM60.834 59.6245C60.7734 59.6888 60.7118 59.7522 60.6491 59.8148C60.5865 59.8774 60.5231 59.9391 60.4588 59.9997C60.5231 60.0603 60.5865 60.1219 60.6491 60.1845C60.7118 60.2472 60.7734 60.3106 60.834 60.3748C60.8946 60.3106 60.9562 60.2472 61.0188 60.1845C61.0815 60.1219 61.1449 60.0603 61.2091 59.9997C61.1449 59.9391 61.0815 59.8774 61.0188 59.8148C60.9562 59.7522 60.8946 59.6888 60.834 59.6245Z' fill='%23BABFC5'/%3E%3C/g%3E%3C/svg%3E"); background-position: center center; background-repeat: no-repeat; background-size: 80px auto; } .e-ai-preview-container--idle > * { display: none !important; } .e-ai-preview-container--hidden { display: none !important; } .e-ai-layout-button { position: relative; } .e-ai-layout-button--sparkle { --animation-duration: 1.5s; --opacity: .2; --size: 6px; position: absolute; z-index: 99999; display: block; height: var(--size); aspect-ratio: 1; background-image: url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0.25C3.30335 0.25 3.57682 0.432732 3.69291 0.712987L4.15981 1.84019L5.28701 2.30709C5.56727 2.42318 5.75 2.69665 5.75 3C5.75 3.30335 5.56727 3.57682 5.28701 3.69291L4.15981 4.15981L3.69291 5.28701C3.57682 5.56727 3.30335 5.75 3 5.75C2.69665 5.75 2.42318 5.56727 2.30709 5.28701L1.84019 4.15981L0.712987 3.69291C0.432732 3.57682 0.25 3.30335 0.25 3C0.25 2.69665 0.432732 2.42318 0.712987 2.30709L1.84019 1.84019L2.30709 0.712987C2.42318 0.432732 2.69665 0.25 3 0.25Z' fill='%230c0d0e'/%3E%3C/svg%3E%0A"); background-size: cover; opacity: 0; } .e-ai-layout-button--sparkle:nth-child(1), .e-ai-layout-button--sparkle:nth-child(2), .e-ai-layout-button--sparkle:nth-child(3) { right: 12px; top: 12px; } .e-ai-layout-button--sparkle:nth-child(4), .e-ai-layout-button--sparkle:nth-child(5), .e-ai-layout-button--sparkle:nth-child(6), .e-ai-layout-button--sparkle:nth-child(7) { right: 12px; top: 22px; } .e-ai-layout-button--sparkle:nth-child(1) { --opacity: .3; --size: 4px; --animation-name: sparkle-1; } .e-ai-layout-button--sparkle:nth-child(2) { --opacity: .3; --size: 4px; --animation-delay: .7s; --animation-name: sparkle-2; } .e-ai-layout-button--sparkle:nth-child(3) { --animation-delay: 3.5s; --animation-name: sparkle-3; } .e-ai-layout-button--sparkle:nth-child(4) { --animation-delay: .5s; --animation-name: sparkle-4; } .e-ai-layout-button--sparkle:nth-child(5) { --animation-delay: 1.5s; --animation-name: sparkle-5; } .e-ai-layout-button--sparkle:nth-child(6) { --animation-delay: 2.5s; --animation-name: sparkle-6; } .e-ai-layout-button--sparkle:nth-child(7) { --opacity: .3; --animation-delay: .7s; --animation-name: sparkle-7; } .e-ai-layout-button:hover .e-ai-layout-button--sparkle { --timing: cubic-bezier( 0, 1.18, .96, .75 ); animation: var(--animation-name) var(--animation-duration) var(--animation-delay, 0s) var(--timing) infinite both, sparkle-opacity var(--animation-duration) var(--animation-delay, 0s) var(--timing) infinite both; } @keyframes sparkle-opacity { 50% { opacity: var(--opacity); } 100% { opacity: 0; } } @keyframes sparkle-1 { 100% { transform: translate(16px, -12px); } } @keyframes sparkle-2 { 100% { transform: translate(16px, 12px); } } @keyframes sparkle-3 { 100% { transform: translate(12px, 8px); } } @keyframes sparkle-4 { 100% { transform: translate(16px, 16px); } } @keyframes sparkle-5 { 100% { transform: translate(12px, 16px); } } @keyframes sparkle-6 { 100% { transform: translate(-8px, -24px); } } @keyframes sparkle-7 { 100% { transform: translate(-20px, 16px); } } /*# sourceMappingURL=layout-preview.css.map */editor.css000064400000001326151562376750006567 0ustar00.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; } .e-ai-border-button { border-radius: var(--e-a-border-radius); border: var(--e-a-border-bold); display: flex; align-items: center; justify-content: center; width: 27px; height: 27px; } /*# sourceMappingURL=editor.css.map */ai-site-creator-homepage-bg.svg000064400000010032151562510070012424 0ustar00 product-image-unification-example.gif000064400000357001151562510070013742 0ustar00GIF89arrt1=/ZY{hN,̭kQ M'1u[Ĵ`<"1#Rb @{7}! NETSCAPE2.0! XMP DataXMP ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!  !,rr`'dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`Ê hӪEl[2Ҿ x[WܹpK…*(^̡1ŐCo[nk8qǠCXɕr3װc?p˙`صGЗm݉+_NmGMμuo:Nt ë^8tҽ~}uguZwxѦ]Kf7!J]V`H (2w$v`a0G܈H`8~}uθQ'io+8LVW46cT* Yʭ%BfHdۓ衚p睯x)ڕ砠A`&ʁ!hV?Vd馗槤>v>ZjEJF:>j<*h ,c뱸Z Oʪ,[-NCֶ6{n++&Ijn[믴;pN#c0+o6V|Pq[#?ʱ6,נ^˫\4r4#3VХsH 4)7Mt,;3ժ>\Wj3QM0lJkڟz p':63e 4iMjlwL}K6}Yy3g-sl?#8ʭᠫ2^zj^밓I0V+.L>[ |4,|5ƻX)+<l o;?}k91ʽ͇?>SρzԶ%(y6Oy`͍ @l ЀKWBF/i"!%68_?.P;"| $aGdHE*&QFj0` ^i4Q 6 !~8hṇgfXBxԣ GQ4P H1DE"FZ2P$} %!x!!x(WH%>Ȕ'+FVR(KN@-y$)Txl%2#;'28Q61Yi^[|wYmp%xθE;2'g.yΝ1`9";$*Sa,Lg=eXFhsP(Sk>%Qs9t8e#Uv+LgB:@-T(p0ͩp4T|>uJTvS6hYԦr93QZu aSr^Sh~:9Ӡ`MOԩjv"#~%E\JE]Rpݫ`GW>Zb7RMb 2u=@[6T*6-i.w_qO^m_ hnrrOj(o '3,Q2+b6):zt+}P*-ϣ e)(OO ) s_Gcz`>Ua76 =W6%=9W:gʆhg=9_%4*HM|{`gMQmb97Qk~^kiksfiG[iѾ1QxR R[N r jfk+槠M4a\x%MqLIeNX|;nPɒ4rw4-2?mrJ\~Âh6+殺-e  {PkuKKva=f%9FbKyffs,QM!q7ghSjc$^\|<ς8f|IDB̹1 {&V/.Qm*c{|>O/Ѕ3m:zZbf9 ^,ܻ'ܥ0)3~Pa ʅAG MfgKEoF~)w g(M FG 7LgwKYu,M!f}pԁPx:p xvF2<v`T UT hRhE'YxD+HoCwXHEHe{C7nnJp _hDI8ڤ4؆ll {XD}Hos(JMh׈4Ĵ5(Xwh'{8 &C{s؋8ȋ!!,`!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,`!,!,!,!,z'dihlhttMwopH,cKsШtJU6z.%yn{T-Na3bzv+(Lp7~8AQ,/R7B0)EĉʚˊwEDz*TJV>oSHʬw KÆ#J!&3jlqǏ#:JIQ$ɓ(ourɖ0#t33J_8tU竞>ytхGL_z>RTѩbYׯ(h"ֲРrG۵ʝ+*](R˷پ6#x+[iAKLMB 3!?MO^^9R&nͻaGwqw'xHkX::W۠O>lßO?#]?-;e~B} `D-f P [f!mUyEIxE I,2S.E1b#|;GHO#j8-WG7K:)%HLaV/Zniʔ!][ixf6pMI#Iu]*C∕{"J]HI) .aCUFrߥ4&I  wOiv6aL!ҁe02S 7#@صTal,p\_#A&+mnִR.Ifh)t{n+) LD˚ʍ;1ѻ. ʏZ;«\B̮CB`̗{qX #!,y'dihl뾬atmx|`8}:DL9ШT!E1ikrJ.汨؊@|Nvm0Y[psDy};Hy'j2"a,Y)lALhDz*U<-Y74)o̓й@.F%ޙż365gH E.:aQIG(5Bȋg$t*W|rf|kڼyRÝ E$ŞCu %3):^SH3+ MU*(=dX<6-Ow]ݖ`]XO"ۊR8} L0aE=,bSU:$f9fQXϤNmu5kws~mΫWMg̀5;x E5N&vO}JrNP礮]`,G^y˟9Q=:uX )wHG (xH|  pل bXxi8L5CvT &5νȌ`BʸpШj(C0">yE xM^\87xe <"喊f/9.,$DfOYT&oLr'5|ɧ!%@Ǟ! wl*cvI$1NX)|ji^is FªdٚZ` %lJ6+HobkVh&6]v[ޒ[GAW߶x ZJܰ{4-(R 1\10qo̭Ǭq B|Yi(KB-ò1Pȋup3 'p3++Zm9ݐ2EX249=3,m` JUxr>*J$G[w)f6Ε u|P|./NL3o_4]`$1~#zߩ"6d="9gfL {۟D~GXFH(`|~֍ &< %ƚ B\ SP|5 5++&,2Ta^Ru+^5''LZ<U17/3 b}<2c1)7Sl<˲&nl>.mFgBC$Q{"3{sHP<sc_͈bMXm]H~P4zܲ́s#}p5y}_~'ɗ@%: K~z wP7Oy.ϰ;勺%M:X<^ } +8|?jr^6彑ğ[5E J+Xy%U#&i؄ ph/GW-Nc"Чs}fp טa@3I2g )e7) :" ޠ t PDذW/NY4) 9!*i^07f h" 1/P3x*4 # xhІ/!XP^p'E~ƨ((p_ / [%#`NQ[#@ /(iŅt_ C@X-9. j Y C`Dɚyf:wCWѱ'PF6ߴ:@p9/q_l`\QNi|nXnL<-u ;BBN tBC wZ,y ceC8FSx3 HRRQ''ybtH(/[9>%U;-E@]柤v*ܧN; _.N1dԩ-8jLi!,x'dihl뾨atmx|/# X|ȤrlƎg6XCjvҩsL.Th2%'iؑ K"N~b" "#/}U4@_Vk&<'pzb3@YG`P=@n"ya+FkzbB3$ѹU*w]Lp(Fʹ) G+D[(z)&yŇ]p&C-5>up& w:+D8,͔1A6CjidI6LL~U}dW$Y}<{c$[P1\A^Rp!x&d^k9}hєH>lCK #d@ny36% NYx_ v8O7 =tevm21߯:(oo_?nZןrҀr.m- xNX18VADPG? H`Bh*b hx >xب@0N4 N|G9-6t(D9^D]b3uyg%FYZ0)'%KJ|:5VJƞDS<<ˁZXl㤘 RqI!G}ԕ:~KjhUʛ.8<5l2ۃ*- fRWD^C)Jfr4|n . ZӼ6T7Z*bR̶ (H0 =P1+ܛ1 Wq(u)'+L%dl 8%ԸM^@N!%ˬ(lsc0P_u a:vtf̘0=mɔͫ4F^hXs\83x2_SW[+΄N@CD雱+LۺΟ;1%_:+=zCԥΘ[}v4|:ś0{ G ;{%ng)>m~Ш`'0u? 'oB-p5b Ї)r>0% .-iA?ƀ_{ A#[,Z05t sAᐇ  z@$ U 1LD@\S?-X" @4zqjscm(Q_D 5=m[V=dԋgU, ȡyC"Y I ad"C^g!d;$#~@"ua@:#pP:x(]2fX~ObZDlp㐃lBF])_)Cdk/eJ(vU[APK![BC``R#@N*{2W@J!pLS'+aaC1cRH!N&!99Yilbs, \/2فvJ:@B+,4"z.QZ*r#B3<֗-π5@f070tW0 aX0Q1Q Uky k 0ƲCX, 6VXcCeٯ+yV8;"/xi${&7B^w['vŅowP>bj:so Lӵ,T- C܍h"p\A@/u9'QěUztpE*BL\L*"k ܅G;!Mo t* сkUHD3u16̩nM|&ԡ%0\cU6J ac0`,!_"!,x'dihl뾣tmx|?dCrl:`3R#lvPjTQUdr8fGh p? YVjlB v4# | q#e-Am""9& vVHU2"vrm$S9I $4m R"craۄn?+bTY\Q+vC`I5'TnL;0L '&  )Bz[3aƝOb H`,\X2߂O'0Qxq5\6Pu;CbK\0@YPQi|gVa0р~P%؀15\2aP #S?G72u^xK2}6y2dfScXEheD㘆(ahbh(٦zsyE ,*$p2ى Z򳎘M@B6$D@)V2iBpztMT㉭x(Jk",_:sd"k31K߄*m?&˲מq㰇seK䳦`-Ʋkj4Nh@)/@oM{ƺBj30m+aj6\MrU{Ƞ"[&pHC,sBN|+K8xr ǣYP GQ}/" V0t(/4$0>0//Hs]ɀȝ o#/݄Ôp/LӀb#y,HUs9`k) /nB.{ 2UmWx3|͸v'y> Ƽ,k; ~=˙:7NطR3d=3>ﰳf^'ؓ;l':9cc\q>]0q@_+>P q9 bq (v0^8~#4rC~7{a}@ 8a-mLl(zREB)9ThB&pI&ICx\atDA<`XTB?h!O ҐSXAe#9.rmtA?,xQ$%  Q RJ@ky2fG^y4LE`l XyWJ.`*&#iuDf$1IRH m3ˠ5y̓\#΀`&ܧAKi у2 4&yL&" dD3걠BlÏ)@kO D1dl=S=3,L* B)/iIT:s`ZM.j ~UA)VD5!GQK%P C BSd7F)Z|@(E}Q5n5Ee֘_ vX+s,D Riԫ/sLkW q-.c ̖N`Qg)U48xMsu['O q"5)WrۃkdeC{5ӥA@Br@& #.rr,XO_{y5@0qBلL`"7yUU Ck$ԀNLe`u1܏sXnrIc Y I7Aâ3v=X \Ql.@@Ւ)F_4TM^ ;[jo1Eb|;<0 {z@=~|6峣43  :>RS݋aռ uXH~m/=&LEmΤĩ`g5P9y͟6tf RAC?&%܌{%QndcnZO~~º(v^E &BHo #?."9Sh*ne1'C!,x'dihl뾟atx|@-5,l#dpl:PrԙM&"b8g1֦ѴzȢ1!>'#w{_ UmSe4w $&'"_T0X %: 6EɏU"Q >Hda~ӡ"+4^ D3@•m7uZ2 6 ,e8Ea>0+r zZ`<8a &'.hxpQhyD` R6*b@N+N4b2BTsZVsA_sq`\Ҿ= H 8YX  Ŭ ( TM]_p3  LdА4l`$Acă$29!_1Tzkx)jg|P= bHm t BAZMDoiaڇPT m\HvϊkHПb"tXXȆ6|W4`K!W$-IO:рc}E0AVUGsȘWjGĕo#MeCOńiiavq}QRhOvԖ:ڢ5#QiQ:vрM@uZj#:O6U3,-bQm\7yƂ~4a&K(BD(`E _~ԣAPMJv&ꙻƟ*oY@@o~@@\P'M-A)߀p5BTB&Q|#8<ń37xX2 F+Gp+s͜7!ސǂN οHqst.L</br*ӫנJ 3Lvpf28(mpFDX7G'*7!N8 L8 (o 63en t+cɼ.J꯻lõp֋[wLP.\7+#ϘCb|Ȼ@w#H^ \}􏄵= w2ͫ$8؀s9Wq3`| HW)#~ [(г;Jē%  Q}$wfT̠G]`:qXll xA{AMqdMyPޓ,E0*B')@848@%4b骕3OtPv#AE p#$R( 0q3)@:t7 PyRhA ;ଏ Cf0+P @&8T!3Psr8Q8Jy, Q zRYAI$4빓('e ؒ`mXQiT˂N5j3{/xB8@K@ր)] 2]6>Ы!^P[ G@ B</?0pf9-7Ab@qfF9dr'U-oE0-ێ͍U5BY;x;#Wf<@O¬3r0d~C˽Xdٙ|}". wls > !,x'dihl_םlx|٧Iǟrl:AЉ&c10-h-$#G4HGNPi(R% ""$ %t(I(3B}z$#6$"pmDO"z\gR "%5ٝ&%mR1ڈ#_w& raT x* )Hƌ Hb+CbGLL` WyM&76s)O\u$ƪ"@@ x^B#6ͧe]pLcXJC)vK[ 4DqqL9P%:2jVUG ~v&yuq-<8ql K*dWF;lJ1Өn8 dP]AA  ! uՅAJ]|+`] >H[[bIWaUQ{mD٩$u(6[2>(yxZQc 0CGAB`SݓEpT]\̉]ac28U0 xjs<\b_6=yD~jhYczCp'(E!Tvi |[*4jeeJoL*+ $(nz ,˅I#ņŕɊTg /Xy-GCs-E-\`Ef,.!.t ǻ YWj2~ۅ,Lo2ZR؊`p¸^Ɉcm!,NrzbЊv-|LUP z-ʯ0CW :+AN_LD Tp=D`8XJGXa` f d_cl=PF_Qgt.A̯0XP}Cz/\4Wդ"E@|J  DlPK)i _D@%#LAJI>LN[]".&GdB*09@ =B%TAi#s%x}E`DLᄺ؂V@dH%@#-*2[0UzU dEF,yC\ k4Rcc21J DN6 5EpΑ>p3!ad9@6w`M (fC$]H H@(+62_h"Q*hilC,@CH)Hh'XW:ӆ?q0u8cpΎŔ/EDt`|ks> 2^tn,j\EB]`2k 6N-`g0-뚌RyEL*\Z! LVFm[Ew իh !( m," gY⠭ H)LmZ0P]s[խr[ޜ2|_QA k0T7Z P[ *-@W\LZ4K"FA/ ;$&Ep_!,x'dihl뾥Avpmx|"L8ȤrLEhi`L",h*&RC4Jt HKki] # """%'a2,O%8# 2]T%t3Ik\{$#n:t"}Rd`+ه & FWD \fR Jy+(pRXF* \Ыh{BVJAx2ێZKbf#@ muD;5#`@Vh,DDL%s'K1=2x`Qǚ2:T<& r`fJK^;bQ11UMOL1*| ipLIJ}M'Xu =v)Em)q]נ,,TR'~k52'M Y@GKz722J KAD6$=Ⱦ*ft : '<^=o/G݄OJ߼K?B:,C8`O>@C!?_(:p { I( q~$t;pPB { #uܰ6S!6 b{KS'J ǥta>,o -h-JƈkHe]x]B@cHM(D'b8#)(B{R/h4Fs|p-H7KH(e&Ѐ>Hl4<% 4@ ˁ[q,d  /m7 4ypq\\{xArW-uGenM\XL_0Υa%L QN=%3x"AG4SBst|â"K-pz -C Fd,ƣ,H \*I@ApDA(9E JB$@X(P*NS J'BA'qB`_hچ o ËbDȢ.رc"Q͎Bj ;N0Wf Yߚӭk#0l nEZ [ ,݄lX͊e݌قQ=s[z}dAՕ5> ۿgo+oMV['pLXa[W@z7%yC!,x'dihl뾤tmx}pH,ȑa->9:5z`\G,&5JQB%rx#l&$' my@~/?o'9$ ?x}cM$"I##z7\V%~'?\(ˁ% Y"ۙQ) "`2 (JG? +v;d}х\_<$5 <.a:p0L$@ 4o,i ci2J'>1u: 3t }9rjc!Ն] k8dI˖Y()uo c@88`0{<&WȘuH9+'HC0aҨo45\uYC8w3d#h&p˙x"^ǭow'RmȽ 7p#\?kdF| qX)Y9ZI%aؗN$xaXP}i&g/&^4ƖcnC8`!j I#-*V$X0Yvu:J%)&Ff0У/h58&&ѩ'jgP0/ÜihL hLKD"C%ctW8ȇP- @^1zrPlʿKSJH%ĠP͘K|J:&zA f{4sQamD3-T{50SjUvd\߄߆{F3q$Ǩ1AT PJ!>z P`p7n-{sJLybN }|\l.9ѯzԳ< _9Q:?oaCdoGJ=~>`V#  ԯ}; Rr/4 !? ~d8 16`.AbSPxM1x 1:gl `Vc@t0V €zH@Ri1mP@;SV.Fzx6 ˆ XgeQ;@dL'VA,T Y@ <Q2aAI/ C |:C(huTj@FCm+Xi)" % &IdtYKs! 0K(-Yj` X$=ĝ؀ ׁQ3@"ph5J>*@(y_;4^ְU!jN_@qK&Z4#pHuS{YQʂT|Ap_I(aE`$ wTpizs8ס,@] 䠊0(+HƋ4&% xTO>&1a-+@.C1\wHPԬ&Ҕ75[hەTU/c66WB7 -0;E{&l5AAd`܅t[dɚl,j̹|: ?xo/3AyWσl=cMߗ@~ļ`c_K'@ `+ 0>м/|kIp< @&(p0 Am_ '&5a A`p} ds zM!v+LҊ2$ٜB04C])$pUDh;[ă $}0@dL  AyuH 2FEKE)@0O-#H2'x??,T`k,`aI1TR@%D+1"?g)J FU.lgH@HI&ڨI&$3$$ςh XXr3G 0`q (398p DFG#x3L \,R  tR 8R. PC:p7J4źQNvҘ &G5SsԱ f,&+*)$– x0ӳax0|} CZVUO= #VjdUXmFeY`C@k:,=V{z cl_>- H+y'm& #\ L hX'uEŨ|-AwE^!ZyW]B!,x'dihl]x|Ϡ4MH-(ultJZSQ9p2OT|2dq1s8bz: ^}_>ꋋ3Bxp2:zUNH4(GM9_V8RNbE!(mx Tq\vq4 @u@)^NDZI^`uOa//VYEJAiYzbf=i2&cߛe6D&Rb3WNQ Х(^磔VYhnl)ABM7֨?|Lvj$ {4bbU ݯR,,GI%N(L%<-4+2 f,@3(.8 t Bm{~ᑛ},{,榟Sl@:pl%64a,(蓦Lˬ[gC*W\D$//]pyyMܻ ǃ/ip \>P <ܩPF g8 va L:E BHI0 ޏ#WVR+q@lNa83BmĘtmpYQb dS( py"|K0_ȷol+0 0?!,x'dihl뾢Qvpmx|& Ȥrz۸ bJh'6hI:n:6r%8/ۤ$`" hWcP JP0|ڃ{Rgsw^h`_fz fR*M , .1g$X! PF{moEe"BV})"AbE[ 8Xxq7v#/5b;\0#DU^R|M!jHLYX"Ypq(c.`5f&KMs&LR矀g-HP Rv(rvA8h GFz)= ֦fi&eiêIeJ^%$ sjrh$%O2%Czw,Du.ojZ ^0[8w7$ 0$#<-J 8H[JP/9h{Mo V{S5}Z./T2>Je%tpDZ1%0n ݎ܃вʑl0AVܹ5R В~sDPNDZwWsueKn\ۧ( oκ(ؠ}4$Kv"H'K8Z@<m@Se{O< J "ݐÅGfw|>= O;qЎ|OӏO/x~{#{o?5H/Lq$>`  G `X ZP?3Mu>9ݱf bi. HíPIQԌNH< \=S!16 " ǝRGL-H9LTAᮕX=I$y(p@0]`)Ta6M*`G>]ȠrC$$r0/pDQ=^@( ^s` {ЎRph@ #By+AƺCt DŽjM/MHu̪vu]dXephW <~ў9+2@L9`3+-޿4Lj"@!A:^`m tbP<*4=7> $VOIlvî$zdG,08/Yzhp}bVIs>.m4tPۀ -`&=Ixv Qca@P 4߆>eP䑨cub@C*rA\`?cer8,#dyڐJh@L@PgRW=i) VU)vVIĈϘh}kuQZ9r=#hYS}G~>WhZUܨhM"8hR7iS~љ5A c=H i,XDJ$Xaꑣk =!֩ISl\d.+8mBHvrZvx*n S߹($`[jj2Sm-K`+F3/;p;텻%?GOE!G;seȂ$ 8s0,Q F~V(, + U#Ot ꆂKojԘJI\0@hJ6c݃a50[|KNw[7e݃Jv{&U*%o [ :lt,7w0D(V?[@Ҝ]D1j㔷n.;8EG y|0{o-3@FL~#_Dr;߃Wo=0N>?S{.@z.@}ǟ ͞ >- f,Ѓ,_'HAHpvx2Xxj쫠7n:H8]P0wBg0)^V:0AhNS !ePC`lt\C< f%/bB.`&"X JS,r!4nl0 # hãȎ\G{t$3os8ab4FN> hGيEb٪PD^O AXAT  BXp-]\B0P>, %ds2έPcA(9MAifk%H/$ʨ! @*tf, V W)5h :dFY_8@|x@}r@@D[uKpC!)>+Pt`9w}kZ(ˆS#) >Lr@RX'ӛ-uFo1<ծV^UK@\X5*L`T;XDzS`]5 U Xl꟭2kʘ\6)8^3EY~QT5,jKw4 R,4(1hٶ\K)]*a7\׸% nr; ]*q\(!,x'dihl_Gʟx|@ȤrlB`Ar 6hΰxLV" h RF$ġAˀc`#|2%"#&" v" 2_/6{< (Gc 6V6>^%"t9$ +y(5G rmKS%Qj-A%\S[ hC ` "ؠuc:S[h()GeLʅzQnÙFiH `NZ@ǧ49%%J RA2""W25eDhc4 Wк 8$x.~qL8@* ؊H 5KDdNxy&CITd(ְ\vY,JsФPk}|uaH|ͣKⷭ|: n#N݇佻^ 'y*`>ؿZU Ps8ux:aIP`as]03aσ (_&ȄyA*&v1faTH8@CsFq0,ҦO:Rda\t%sIf`tqAcve:9P9NRCzd`ehZ-*T!_"ͤJ$'5K]x* @U#eY3@՗dz^vk3K7,X˪^ޖb9Ekx-DdP,<"I*mƝn1> 2A[L(XK|#ʂҰ"Y$߸K1(v1 XQ SXq5ezj H213#fζHl <@=F0$>()5(YEq_ k^{s؃ 0.eM 5h;a@jmp㏾x@@lEw3A{\0o?5CH(Һ8 <:(`Aw,}\RAF Jȋ_A1f>W:a-#"`@ Ed"1=\BPJX 2)"0>cjgQ~!8"@ XQ!Af&=ghNӇi2PcƠ@݄PP!.Y"v`K%2xJ+☎㒂@~`jd1*_5( A *v! CH (*+PrrE.|:$x V-H G9!y~)?6"4@ j(4”#0Lt:klf !Cʏk-de:(R8a=Dp)B}47z~e*#1`[NʤZ@2:Y @Wm1R=+ |U3U6鉞B諃j6 I [:Vt_$X(PXPL` VPA\3KeP*jLᓷtlkKHʄY [U2emoYSp >1^-o?]Quεn !,x'dihl뾨tmx|*RȤriECgR& Rd82X9dGQh>R`ϱ~?eq#&) #T}9f%'<l$QDC#K$iRj_w"g5$2yԸQ"#]}O(obC"' P;Rc!AߴUD +9bzWpѡ4-P֫ߜW? L](`I, \RDZpu# ٦$PB3@ eh2-bש^E0H1<B$@ Q0q LH6"S~ANEFy *kRK(X&D ۆM< Qo)@K@ /"#=X"G1|e!'1BI#k :Δx^r*]V0`FLe K@(CLQ$Y B2g2EAIO4Y `Od $wPTJ 4)-+U x#.(1D (H *h$dc'B?RH jIӻj$@{AS =t r^QRڀie b1.yupd$bAH7CRbFph`[` ilBG\H6;2bfWlxf1WIïIgIÞP ˇҦ og/Кlz:(2ZVݶ3q9]{$d7л%kxE0\._x]^w'!,x'dihletmx|*',+Ȥr5 D`dAHz`02!Ed 1=>L)i87 )#3QeDz.Z#"4%i$|$"]RH"#rY.~ }ZӐԾ"p[ލ2Co&ǂ:' QpP[%C \pńu3j@z"|'y#JC*_֢L 07&JQێ.tӼKdLPUmPb|-a9z=`D0uݻxkÂ|{ DXml#"РH^{όh].2^[-@,soVr*t"M⬜H"8`KiS 3j9=jd?h'~h40<`xxf p=i$8@v l}P@ljFhHl2VV9UHEd^ tLbEJBɃ @>HK f4&P-j)`c S8_}̃J+Z1PlBX( @ClB )\DI\X8&[VkH0 Ipɇ4pRMω "KHvB!)<; L6\&ESU[ =X-]s 5 jVZ'Z -뭪10wv\UIZ@R>5XՁQ>+#zs쑄)T(캢CZ<m$x 64x L5?ئ 3. B榠"~ $n +!,x'dihld'pmx|2 C ȤrlEZd2}Ҁ~ GxL.f"HJOeIyE[ o$)( % %E+#q <"$YDzfDw#{SM #@%ծ֛2]2f{"+[m%ԇsM@.Ci=\(CIdQ?:$l9٭ل,oC39&k`@& h`]ShO{>mTu)XQ,f},ȗVm=~y/<~Y` 0W#ADE2 ,#)@󈰞C.9z Ҩ]4)ppm QkӻydP*6K@#_μΣY c|4n:i )5dQV,?v+MJMN'@9!zCT`8 n(bma!K8!.DP"Jhpb22Gc у͎M=d?SݑL6PF8Ve]8t%Dx%@qfet֘? % 8x zc2c9@ cD";(=eң:I.vQ馜 gB$+` JPBhj LpA0hkQ_̰ʒL6KBmi Dˊmk 8P%h$H&ղ+K*Kк `2&M [#&/&2*g6nb> -ʕ$+D̮" O۰l:[́rA2ah+:p2`Ȭ,{tD:zB}aU"nvMo&1|l;k~GPe=||{@9KOWb~/ ?/X5@#Ҥ8L @^`{plWQ 8AL wAá`BsqN  w#o"dF4$z^1=2$s?%S܋#ݖ`4%|$MuO6\A?ڇp M<P.]TѬ ?`!ɓ%|Di#~,, zٌFc;ahp؀P}ti0PF]*NL=dpD+e!A68C'ݻ4ŻCp`Wa'2+x<&U\[8*,g$}*Ө E pj%:6`i<0]{C!@)W+%Y& DV]I$$k׎U=j˟]pdc)A"#^JP`D/݇<{&8BV¡d<ڈ$^uuJ3VM >*72!9F _\-pA`D& V(8(>ClgqACn pMzb:Ehi"'rpYK9gLhe!oB0@ ,@(>:(Kw"$-z~* v BI3|Ȃ8 CP E#huB3"(N I`N"Cf4*$>.p_4PIc ȰL۸ AxF}dlأh'Dj)̤e.N`XpdyΦDA!pU ).<竑ZfyL@hڳEZv.] ^[H&WRŐ@pYτ3aW#lΤ{`C,k :BIT{]+qA^f@/ & I|9F }$Rڐkx`ĦӰBvh,$D,/T- B~;ODf=b.MsOv-{B*"0 ~p:> KcJ;o*bm%qc80,11Vs'es<p£JP4,[Ђ=AP ^Ta-]5B +3N `cwr3s|pق[oLVL.ڽ L ;Z32s.,uFAPPǮ'lxG z#ozm`z?-]QC#/B^xBݨϾj8P.v~9 >"@V0?֠1 \@L@P}Y00U F-@[8` &P`L. @:PCx,К\$D8U 07L ̐"i@TBDH,\@b,@hFDdYPT8 (;ɦZFgL d%#P#Hp%(Pɍ ѼC){0'Nā dbaJ\$!@#:N ( t( Œ:Cp*x Hxj("ZBNH #_&>ݙ3 RE, 6Kp @'eUD;M^{XBqQ2 X!t֘\*fu:@7LO ͇YEFO,A'TXSO$5 "fX%hJYa6ݪtҪ:I6dPy #l+ :'s*``U` x`'{"~|\@fhaP!eV QEgCWDR\j 662-YnODVUz ߖ`#0. \ !,x'dihl뾤tmxى2XȤr2t"'"8Q`ezh8RF4HG;M2?~O4 j %#-l%22d|&C o";" Tw{~R$_#DF%|ƨ"f4lv]ܮ( r(<*l8,#T`‡Bm ¼-Ve/p:n$Kds&6}Ɉ@,gj"0C_L[RMo^yd DeNJecV7dPc;(gUS͉Uv&@ NNRf/ уjӟ3^6E#qZI)Hu^&}vcd)jKuy*E `窩&+JzNrAێlo 볾 pׁofx+M}vcigNZ."Ȉ%rl$ %қ/+^ēI.% Hq+nʣ{$$l*PĶXČ293=aGQz[`2 %2TJxͬ 6*t%~nb4o2h#lJ(|`=- h,*/07/gk^x~DBLx ?+Dm^@/l2| ?Rp|Sp9 %w9< D3/7Av,AοC~c x%@8+ ih{$"~0 쥠s``a$ᥲ ~@`Ag\aVl f=p$+˫A%wl@`p4%E|ZrNXH&@Ih!H8Y<ĜJ ]2 IFJޯڃ$#4fSaD*F=(D@o#1rF" `^o"lE.h`,Yx8C=1<$ X3Yɍ<*,Q|iՄLkh$(])(@/~xD0 8 $L P Sp5˩I(ƒ?#*.$i˔Xa7@@jD"A;9Q3}Pǔ|\0S>4[7U Y un9a35C톩 ƋsI[j.GƐ]̚UDEOug.X]"FdW|2a\Ve-il׼T3LU5Z¯{[&{4A% ։ˢ${Ѱ-AnIv|"H ~+~ !!,x'dihl+rmx|wb,g0)ub4tJZə0[`H '(5i`DLJ|NW'P%(hkm4Qvtle';%\o2x# YO$'Dq='M##@(҂m ܀%莝5lt*Rd:+\Ȱ 451Aɹ">7] i#D$L9e%KYJj{I3c5} adNGaУ3`0tϦ; ի5؅ʤ;}HVJ7@VmtKT[uWǾ"M@ a+14${ǂ|m\\(cЉ/WS84PeH(` 0vM=@*7OnDٷ6>E@̣K5J `e׉ f hpvz)W@pk= Wv:26X PASMHY~^!HU&E3*6-Zbz5݅hp܈,bCb%UÔVG#S^ []mDbYim@B)'mK4QwQcQ((IFB.L">p@4'Ugci**((z`S640,zY rzM櫱,,`- 999^\+}L$@nm:ʬr3XAT8 .xz00:!Ag4qN @,ʃ7 !,\P+z@&z=sDO8XE;*m8$K68;pҬJ4dCu78h m〜4 |SwW ޡ 8FP[Ns8SDqZ֔g9 nϞmN"9h^EBow.7pr3:8@k+Lz;C0ߺo(.L`ٯ+{zukF@(J<` 6qQPwB7*`铅lZCAhU+*֗]$`*~*1ʨK3 `hTCR#'PCa u!;$bax5 !IEP\nJkrEy8 /P1dnF*`P P 6BḾ q!>`aan MtO@5(c-c*|oQj!K8-封F1xLZB,0`,.?p!%(Fuc>M%8Yʀ<p#cp{@h8`RcRJ q Lˁ ިf,EA/O1բAK|Ё,,piNqg0wJxt(/ovnH7Pu Щt Bb8K;IÃyR0`8PUP0x( \^\k(-o:\Sj2أvWu8EH],獿Kr4I֦"mP@kKZ6!,x'dihl뾣Qvpmx|+Ȥre&40t&&kpzgM0i  )`ID~:% %"#$ i#y}.bUWs$=" 4Sxz4N${$;V  D,4# cēᑿB霭$Zz2n,Q8E" i\hcÇB*"x"TqX8`eEHQ˜;+ 2$Mplq>l Dw$G,鞔Ny"lU{́5 (]NS(lV0ϤZ }AtWD G";}k G_M̸1@y v dQcFfq2@tF'װc˞p6V6wա%.3u V-ӹ k!I⍈!uz$.$ CJ?b=`MLZ0&`Y-hdz1? e2@.i ^H$\d@Fd A4hc`}@>$#:p>ɃKII.)>IDadr`9$XyJkDRM\vFd}A \8͗a5b6CVji(,ݥ9Z0ʩ u˓+ àE (*`kkbm PA)l Fz6vˎPZ1)FSy-l˭=~+䪠}$E:#G`p &ȹn {L1 pr>.GBpX.,lvR1 pǝl01'&l{a?/ "YA8GY :p7G-Tw+EW s֛G2Z{ҟR*,SG`-}66wwEp2pxHp`Lޱ,4p+9'^}z/dA00csʽ^<; s*<¾|C2\7۠S0dȻ > pjsυyH> :~ S~'@ 0 Wͯm;` Χ@,} \-"Ȅɍ?UUК&%kaocr@NnBS0e}B\ 1:9#(hB?2XG@+1pA e!BBY RX X҆Jr4"l-W V#LGPD}Џ KpB$ 4c*cJ_XѕJ.K /~W #s\Hشa:ZN zf ޑ

ЬHx 0@O؞ŞQY |`DpR͙h#>ВZw6!Yy.7=dAUoP}cp)}ACta"qL Ėn=(>NHeOTd@߉Z?8"hlHS:&a@ЏBA)_I/DtZp@(##G d`hgN缗$IQoAߓ Au0@\٧[ǟ9(N&.&5_Ejip2⥦@0IȰ@]ʃnr P`/+"dR/DdʾgH@s_5 ?kN#I*",<KBbŗ0e yVn͈kEr)JJmO/= k/F<뮛ؚ(0,4 Ɵ5+(; qb \HmXO.>Iq`P@:H"Fs1=r;wrHl 8%nemwMsGPDM9G@,iuA2g*IQ|&?LoArk̍%S@N8/=f{TACnHz^;^}ҷ~:ϏÒ0gVWk Խ};w-|`P@ 9` l0plD A`¥WY 'Z-ʌi"? rcqq"qP!"،#PpÝ\@<"@`xR p t$ls:>y#bӶ8#"@YvA"N3MЎ%iN@CTy6B~r#r{MGm"QԠ+A,fDL蜨ZҗK sM%P0*7Ì`8iA#9MMCxˆJPacp@8c|&d\dK h8@`Y:IPd1Fm$=@8bA (?PM@fF !" iXL F4``ASec$`"Y` ̂M xS\!e|" HwJEL>_=Ljj UԵnOWe8!3$G*hM,3AٞZ_=o| kK^,v ee U<&0V5g ,bT,:JhΈ@h7Zg,\h=Kj*Epw 2-3 0` Yx$^[ % u߁@z{!,x'dihlgtmx*?CoH,H40t&$GDYdQ6z7!i 8(e4 (Ob~bKm'%##M}52%$0#pfVyk ]%MF#}"қesя*p)B{K&[Gf-RD"*l1f WHQĊ.L#N<θE š ZF@)5:)rBF rtjgKE,`Ҟ{ɿI,'pF:8N<1;rd7ڃg=:_/M/TJCC/P,K`YE@N|YL Y@ԍjTAEFcyɌ6nt àބè=f>.(2ƹD%Fcz"(P5b ,r hK1d`Aɑ8DR1t$rI`DMLLIpDlI1'm?/GHM.2Pص aDH"Y؆$цaE/pb,!8A:2'{F}H@i*#D P,l19E !,c(^wo!΄b!|DAr1/x嚄b~%HdPB!&TI ,yog8G`.,N.1AP&Fh0W<-!yC/a O^N_0pIF%"K;< lXUL쥕0bbBQb4$7f ( W$,?[_G@1ѽfBij91 6%aɳ(*zMbdItk&2 =֫%VeGKھim2 +Agmnc5D2Xc\4Zbc>W-sO!,x'dihl+Ɵ!x|06Y[H:tJZ/g9<>IÁqְ|E߆#z$OwtNj%~;" %4*6$ Q#X~ $mZ"# V%"3-_'6ˀ)OÝ+tn8X9*.a‡)Bܑ!L3 t|< 8.^̇a=8ϟ".|RRP[_~E^80 Ϸ|? `FtgnoL.\k4 ]5 Zj T>=t(^ 8 t*;L36!t&#lÔ&a GB9N3(RʴA"16ppF{  N8 ,1AC%cVY$-  / ڐM tCd \<1ׅ$I6 ( ?<@$S&qvD6ލ=x"i!R#-Y#TH.8 0cu&IhqW<`JZclI)/ ++#f4L,dC8fŸ}(AuM[@cb\RbD B @Q0@r@6YI4(hx2#gd҄PRpFtRDX:Ny W\D ЩqhJ[,! +W0D jH$t5'Z#ڢYը罬6A&Y]!L v4:Ц)dLS4sW: RcwdG:VzD5%$vWQK[ Q|Ս_cΊDKHcK!y- [.P<TW !,x'dihlf'pmx| 6Ȥr*hi1 S-ɘxl',fd iEH%mdL_%z %"'" $ P:[}H 'BT4w#L$k4>2\%sm6B| $*4$#ㄪ" 'hb2]+HS6&|YH(b V4Y<ܳH*gCVx(1kh@3Ο!hFwbT !@*U T&WCSdu\ö=KSFuko970)x;Ž--. c^o9!#Jk5m\'ѣZ<,en"_M0u?<}L0渀v$w7}/d5"go1B㝀I~]Ǡh`Ђ DUs`Zh`a,P`5A@@; ~HcUhsc^ 9'uD%d[ 0G69S1 6MLF@``9Fh(E {g"+&PIF؜ṣ/i,:%"ФH-+IFI.ߥm b@l0i+X ̸Tf &Aʛ$5&"bJ2fz,Kd0(D&вN$pʅஉ2@{|B*hЛԺTmde[)vd:hz- ).+o s! p5 y1dʲ2˩~L >/!DAwGE[eӞ '=5P_-jD{MB-{ +m zBA} :NfOӮg;Ent3w@``8:S #;A[tr{;~Xwwp߰E?g.}Y}OZ(:R\dȻǎ;K旰?5 G=  \6` ` 0'A#mT3Al֫0D@I}HQT?Iup_*〆Y" }UY)#v6$cYx ԅwPEP0'\8&І h"Id`ȌCe! 0"Afb+؊qӳ46{xʸ ĝ¹.3`j[hC*dH<ĐE<""ğH#F%SƤ =4<,*PnxB-1D^AKB` !SPi*c : ߨEi H:=A$+3KPJM )h꧄Qy 81Es*1A| -&(6I:s;gc5+=8$\Qu ,u-К~v0.SO;HYUOP1V2,E?3.Қ&iԘ I(TdUP}}_T3̻iyUBIs+5Ury9­j[(6a,v();S]F,yVж)tK[[C[nk[a!,x'dihle'pmx|2++Ȥ!~l( *)BƖxQh vzu~OƋ&4q#"$* # S_|5f%(6%1~|\lJO^F~ "Z"2-2% @ڻW'M (a$&=R#%[+C؂ 9UdPa`\Fi$yK :݁-Md8+!QZ¢EeM U%MhʣW$}iͱhy!GpJ'[D|g`.Y0I0˘37{TI~9!g<x Vs}d[oy oT,+A=F5 ]IJ(hUrO!7}T^^ ?Pߦ?L Ad-IXAH2IAh0!8-.ȓd34F0"yApMTEXaA/g9d<5[SgLiԺ{%XU8 (./l++UO}Ec3b[f{%F+̦o9]jU [?`}Z#\M8hK@ܙ\;3:W -`\Crn ]tC YvS]`!,x'dihld'pmx|2$ȤrLCgRH$g)ͰxL@(e4FD0^Z`2%(#' %g :Qh%"$G mj4#~]I u6i%&#2)tRܧA u&x0?+ Ԧ*Sr@h(L #%ER"л肜( 1|L2A-8\ [ܬ[*{6@iA)&B#CRmh4kuꀥQ fy$%nʍv\(!\C!ta0a4b.vrʖ{̹JSvޡC0AkV'ѐL$7 .uu40}PGdFjn3bP yO|1ӫ79_E$~ W=bx5U4w`\=J8EW}UTA8#&8ؔhTƼ&R,> e#KdhFMeDhsWv9^)s IF 2ap(هsDyyvԀ]j衈&] d- )cP3Zꪬ+tƚ"Prn)e@XϠ2~dF#VkIY"PKɲT7؎iÆ*`m QDckF:p)-'Zak-,u`ibf1+4Wjy1# ,h$`q1 Rr3 "@414.Щ-x:PdK .&Eb{ŵ-An][ "n;\!!,x'dihlc'pmx|4,+Ȥ1t"hB8H 28xsF"L@ Ox|"W%d_wMy#")#% %2B$q "8%s#N2Z&`#Ra] &)#Ũ#$#ڔ4A (n$biG”~G:)4qQ$,BY8\FH5Pp \ĄPfPNټNw&iYDa,^.9/ -&ק_= cY2]%2"HVl\"iR^1!`hL#&&-X3qy.168@8ְx ciMA6aHcKنY4މʓ\h0Tэνw9k~=*P KAy@= `ec_In ֟r y& H9 t-\H,2LaC~)k&k"-A%F]-( GgG9lwcdd藐C*!@(>&T'XfiqP:bȅ\qAgZ{ɉ&QCWhDPʉLpzX&ڃZA]0:F66CqrRšTKiL~PBT꫰ңP*4cS:ͨ2k L@Y-7 C C.+& º[P)-rB@CNp[*,CO -,p:kĹR-J0 /|k> <ƌ# |;-t]F#7{&]m-NJNP:eܱh\S+ހ^:~0@OS ~[wsÞC co8@H| Z\z{:]L; j7A AZpA l-&0@joܓX-tE0 zn K蒠A!,x'dihlbtmx*(YI+Ȥ :Ȅ4  Љ ˰xL>v:cHFis=e"[ $ ' % 'M&D%"#0#v#l\Y$J#4"O q$@+ög%# D[&s6yPK _ȈۇuUDp%P>آ&(E`0gXJ.d~>ȼ!ti.Daʰ(&24,tJ5bG.jՏ2`=5l^6aAY8:uҺ<";#+_.1up sTIxP 2&F۸)M YG m/H'\j_vٸm)I ;i6* H k. կ[{ڈvحɇ0e /"h9rGi\1`npҁ a>d0mmv~ \A@Tk P|+(c Y٘`:%49@p{p@.Q$cPdX\|e1_Iʏ_5Oze.aYHY?W¹$ov㜝xUg]u)u x9V z#(]P @)mij)P8S6S*i.?6cѫ;D"zC.3A"7R'KRV*RSF˗[fOY-7/\ .L XxK* (j%滥>NH㎶Jh ,!(D`j&K7 ~*p.Y,q(ȹɌk{&n[A+ʓ(0ʡq1 3ѹ@qHr 5r6 ζ],ѮL㲱jwqp'F6  |A{7v7{8(hR찃X@DD̆ҏxjp!]iMvcD8 @臟h+u5.sЋzd϶_:90ᏂCO`߾dDy#8hh `,}2z0#&0OzCX_ M #3db"Xe nl`% p("3``HGDb(xl;l+0 sJFB&2pnT|F D>R865dnm2^<`b(^:oX > EL":p\`@"&7Ȭ}2:1/=A^%0\!YYB 801$ HK/%Aiȥ 36N.A3 _!m=8sL%8 ܔǧAGP'E^X 5cvܐ'؁Aiِ6Af䘨;T h(((DF(&0 0c{HcfBUFEFfSPdyE bc68eQs.QK<`nPߪQ2~4x]ᮡZ ;su,.FUeUk&ͬ "4 `@_oƯ1 PBcaɑŲjBYP-n?\wT+P)8!,x'dihl뾥tmx<)wL+Ȥ2EudsXN\z0h"RC4Jq̟h,aXv"" %&(q'?.Mr$"9# @zY#b l$|Eo‘AΜ$k$x]@[*Ot&#_Ur'#Y ѥA+4 )Vċ* c ]N<AN42Q5W\\No,ql(1 ?5J$MJ~0UǺ b [ .-dMBO؎aBG8A}A9N B\Cc2>T\ʘdɂu8-B~Io붯 7v mV)׿2"6 Q{kDˋ4M(bQ`ӷPLH̋G |h?r!j˟zaKF(]Yr i6R=x6YH:(agO88dZhpЉ,߹Hy2~ݘXa:dMpߐч$VdZ=y1J)WYZbTe3Ac&c: AIFٚGgX JtA( L=rZ!u?-P)7TCāBxcKWk^dkeŠ4(Y첪fE:X6XH%J>LЀi'*  #<#g/*@ 0& b\So,!F9,5F:(11:Ʊ*0$,) #@񏚬[&% KԵ\s,J;]EK6k}ױP'~,Tdri+AqwF\-ޔ!5 d9ЭĆF;k3 xc.,@JL<8{9נQ ݺlzIrG߯W>@g @L9l -ƞ>$0篿߂w/0jGr"u Z9 2z C ؖq9#qϠ\izf`G7%AP"+ #rC;14b ? S"1?)%&WP+Cآ=p‡h<8؂_*@@bP SH&m! sH"oȂ(%IkЅ.Y:@6# |Igpc@H)amibT@h@EE,WAf!(У 8 KF ه~+qfJ0ͩ䋞ИŲn 0"Ƒi(FJЀ7q]s8EB*x;+iB ((v'$(i8~PbD=ȧbXrH2&\ `,"X0iS3ʯ,Tu@ 1f"u1ktXԶ'NMR`B plQ 4"}~UI"k6lm*.1k b5eՊ *~6زe y-JoDa},+ʂn Cҭ 47!,x'dihl뾤tmx|uLHȤrdu"(Edɉz40~| -u  %#"'~v\z,el'8#Ruf%"M""cGRq$&. n nع-xB +sLj#Z !\d0# D&]TF I; ^*@& }6-u`Μ-HKǢ8B+6BڭBtTD@+/ YŻcdB#;Fyv(~Dhp9D,ƜKPE_rsD@LQG-Dv%?x]ɂL< uPZ@enHLs!hoLA{ @DX nHU_aWDw"YXW C"ήCвۮyD+B֎@wc3 f 08c޳ ᗿBg;}.߂m_ (@?C%dy`c. *#ڨ\LQKՀoXn" Avc$ аT'Q1x0 ;ӂw"Q, N'*ZIǍ d[@x q rhB</ !9,c/!1D?4 `vCHDL'`&IM"qJUqC $ 7PxpkH) ց PL">yׄ[vJ *Xw$ ea6 35g}l{ ;LEFPF#F pFp(qE՜hQ J5!7U䃗BAd R,hU1j%UMV"@Je,‚h247TaC*:H5 xynx*Z<xQV⇉8 _Ak"O~j šd)Xl:3y,#1G_q~`P[ɦ%/c!;?kIg#-nE[ٶ !,x'dihlitmxmpH,+Cg@ZD~Yd?v0p8HǧP*h>b޼~/ V#o %"- p$c$a}%ds$Ecx{2%|gF2~JA. L"K#؇d#D + KCo(GBD$30-h_/8*x3;htG8&g\`.;t.o,yI i@3;2lz$5!΀R/ >FؑBNˬW: D;S-lm$Ȁ%n긠޿{2`LX$"^LDbCx!AR88!ֲmsC>lְcj Rg`=CG8Iv٫3"N(}HO n#jc߮SY{M(p|N vn>JRmb􉬌CPΖSJu AE]Kz? ptANaD@R!]=4]=:A)'c L J8$͒DdpPVi%9^YeZvEub^8@hU&nIk4ك 8C|gwhQ/o1`.o* ZR6iŞ*ꨤJnYw d8* a,jD)"Γ6!ZjlD'Sh%<@&2~0*r+@ ̚.k・n+3r R2L8g ^anƺ* s yW,1 An+<<ȩ\$;;47v(1[x+t|5Eo5q_haCeb[v}0wVhߝVϋE&E0MxP8͇mtuy0^kF9~~gnk8@>5/ A:L@΂Q¯sS :,y/O}  ;_{錣H>` xu߂s}oGdsΗms^*.y*ØX[6E4@rSAI&pgi/C^hPBv"`.v-Y>(`80oT -"Vae3pW2L@[Cf*Â(afɚ.$rk,H2^bR׆j`=SHDAL,˘5&1o0A.K($^8! ҂"v*M%pp-$pETj0"@*Qp%G@nLEҽda&ǻc q HI/ QY<pd&TD E+k9G@IQ* RF j槝 i*B,4*1ͣˮ-謞^ ETo`渂}%'V[u(>%# \+ޒ !,x'dihl뾣tmx<*pH,ΠEIp:?vr'Cg!5Lydp d^kGh %"%p#MA#{0a(9"sPWx%{ke"2}CMK͞A#wi"҉us%LHX,E)BHAD:P ; *e ;ɕ(uĶ FLN5 >p{h ` Nz*XQ@ 3leBF]OS^GJ3r v?BNhq$YX JNR1gDj$BL٩'碧L O@'&G/ldA3cL#2ͩJ@ 8j<*URRNOi3T3Lyj,UWQ@ѱfuZtM =5<` B3i.%ŌGeɝ-sm}jN Mml'(Xؽ%@iEо͑=;L-keOڪ]B!,x'dihl뾢Qvpmx|&ZM+Ȥ2E$EhEi`dfsz:`JOQ|4""HI41xw;$-#$l$z~8T I&ix $J""O=%Ɠ26d "f3ϕnյWP%##Y`u,H&IE\ジ #JA$*1 5 r! Jh h˛8sҖ9l3K'980R>E0W"u hΟnwhDr{C. !qq=p7~L$鮭Y.0ճ a5.ٸs[aJd ʙ %Cr.5*_#ν{H\<%rc~ 'lD@ yK@"h EF^DH@ wNQDL=! -4}XA&)+.@|"'/6iXK!xD4> S܁ iY:)TRb% 9NayDWUdP7LЗ3E IräUMt' ;7@Τ&D2Hܡ5 F}BTk9()JAꪬ*r UA4٫ 4*;,@DF+:NRьD֎ * 4pfU(h9T&ɢB>tֻVj/h3ܣHŢPf"ƨTq*j*im0 Hp튌7,/  _7r+V/&G+@Emݚ L+x6dkA^Qrݶ#6Ht׽%MmqS4MKDD,Ppwn{\Nod~߆8Knպ9(z͏-y<6[ǿ#νo# C(y(>1FsAȐXzLATfP"278#0< DNxB'g ֨83{L .V桂Da/.'HF|F 0voIH Q.MteO11X@-)[AhAD#g@2Ls:Mp'Zv`czcyB2EP'q- nTE>u2(>s4YDg0RSJr g |$vd0K, B`!O hڠQ "CUҤhBC~ CӁZ“![KW16#B!2:w8LUD $C(>fH>P^̉Wʻ%)-Bk#^U ]%^j % h('c/W>b}^7ٽ鵳%_(XK@jbG2ZL^X@Z: %+%An@r!!,x'dihlgtmx|*2G,$g c`LJNPz!8#A2Fi2Mb~% r'&$"2}5u%9$kQ#LzB$p "NG2# W4dn"%˂#'^,vFN* M oI'Cy=|D|.px""D& RŖL^ ݼ˝{ͱ0}D8FjM 2U`@/+TݵJαh[q`,lU(xKD4:D(p/iGUa=^ݔ#[ɘa;,ٹ; 5 K&<ְ] Bis=JAaw$tr?1rZӳnAM9d#--8^:-jCN(z5$ H`e)Țt4P4ׄH@v!08\``=bd'xȊG2*qcLNq&N8g0M8O VPZvɡ^zzac;Aĥ!G 2'RbӝJ$kX;!@q$u&&+F <Ɇ%M,R9<#SҪѣc 4E]<1A0k9*EF `Jva؂th, ƋϜBA`֫Led̹B&D@+r1G͟twS TdžF&+k20Գ.)k'{@֚8%_/^"2$&/A f~YaHvb/C.//PPofS=w(xE}t حg. $4N0n6#- X^E>a{]9L :WX6%=lW[O,SO9g@o/O4U^SZv*oZH?۩L~H1@p@3SY _/(@*8 Oq@pN H;(ܰU6J1`,Ak D j'ty;jD%N:!Hh;LH 2ݐpK>X L> tARA eNYy dl5@*c%+!Ygܰ_ʘהx@ BH50pD%VX+8mM4MZE@ FW.Dp!$h!EX $'jfSyU1@ $G0BB(7 d lt2%/AI=(fGdݴ =p4OPN ꖌȟ^"uPP 'B^Z g3Y3^/R/(0^LHSeиU7TP%Y֦Ji=UC~N`Aw ֱS$ I] `@[kdDd}@Y3_lK0[V"IۮMlC!,x'dihlftmxh?G,Ȥjh:#,JVzH`q FѤI,(dA~2GZ(%#" kN}7?t%"6@zy 2#HfO:b&$nc6$w[ *N$Gbv&F:G#-"a ~sH+ *LƊ|HQ`Jq>t{ !Mq"@yAy ǡ "q(ĨJ8جC)~ݑ$hV[!{``6VxI$Bqc&S#C1|kw;Vͻd#|OKRƌ;)MF}zQHiꪂU_zV#J+6] "䗧Nk,y,>4P*i.ٲR@ݪP%Z򄫊ʲL<+brEB0T 2:KOk{/F;*_j1+\ǽIrR'n IJ+3 \\Iw60h%wϖDtG* .c:İVYs Զ͒fu6?KEt,޺A̽P@׀P7c+g @<64#6lh΅{. QM{Aәsrw1xH87M6?\NpzΖs=,9wGȐ :q0|3/ M/0-B 01; H rhj& / D&90(Bx ;8K1@ܲA!<00 0peFYaE)%׋ (@=X\SJ]/P*{ M8(@2; 7h'ИE "kȇрx@Ҕq$>>pD=F`&P]G}"0 /EaÊ""6XiMN:B1I*ŅM$k@xpg1KH3]f!*t- zxͻT+hrOMQNC C|)@ T-uXŕBE`hԁ'0e8@4~0APZ76c4EdE `m2=>=(32K|#+T :"SOy}vɇ%T$x0K^GwdFSP!3zTu9"^S@5 ѵ!kjpe-=a!Yzi ͫZ]r%ײb!,x'dihl뾩tmx|W2S'Ȥrd>@6Y&1tͰxL.&4%'SBy&> $&%$ Si~9[#&5p%2Q|]#M# 2`d~m3$R2"O (d>"'"6^ PԂ*A|\w| #@ L" r"DKb?h'd>$!Jy]:Ɣ&@1}B% jZRi N3Y)1]n/E:fu@+nq@,]W.0N~]L LLI">v񎵎K䍼#BWʘsPnvX`3pv$mzGvVR) 84\NDœ'Jhʕ,:.@9ڗp=m箧X=q&yY N~$ t'yhz)W`qP89hM gE2; 8ƈDPM<wo0rKzq@]ȈSҏqODc< LL+2fM&Y,eM4̘TiC_ SbvCШ .BܠՉA ,pӢ/U餔bdVz#Ц+i 8)*jC9뭸_ '-|I#+Zl Ǡ抚2m>~N+%e8Ր8XBz2s((*F p2lP+0$ 4<D p:HQ /64C²#aJ6rJ%wy ,"&J\GF Nx+{踶yN!{񅭶b/ / uKHT ZՓUd?pSuM UTՔan@ڊAn$$IX0e$ڬ ՘F2eu bm@뻚r6'$b[L )l+tE04BXuK]R7 o B!,x'dihle'pmx|2IȤrJZd PCglz02؉& dl+%~PK"$( $4]{*Z$?$p%ZFxuM"4\Gm~U+sŅҷ$#VܔD)m驃?2k*V4*d<:v *<l U</ŋ0ÈLE,F6Cj@B6lY,2Iɔ/6/*@>N@hT]]A&~KI;bsTIߒ@:a=!K+q vDž6Lr$W,k!c=$&c=*h26M ud# +|ߤ qED@#`? 9 ,5Lkx<,^-I`9,{:q K;?KO7V4n .&DPX(sݕ$!(M$`.;- DT/-@Cu])  a~ҢA@ 6Ӟ N ?ޫ\H ^Dxs^x\8(N֍ 4&e`lo! @LY#y ~/TxBMܔH ZzL  cs&1yg <isR%4{pOx 9G撐x"A=-I&x," 8<@q;YDOCc@T Srdy؀%% l #LG'Ah$cd,r-S1\k < Rb`BMa>\XҥR]$gE5 : ѕX0h$GRlJ `!XEWn Wҧ+0@<0=$3'.HxHr]c'!j 0 _=U֯%*$8F`%ArG)@tg;@!!,x'dihld'pmx|2++Ȥr%} i`,S14xBG,#)A>F),0ȗ{zm$+' %2XNC[$ "$7%\{~Tv"#| 2gG_ul%2-"x$ë"ك'溎" &%=VFT`  *a 048 Eĺ"VC(@J$\r`\A oV.ԑY:H ҧ"7Bmjc,u]te Pm8xGxqc_nUn0ƇHDx?*h@NPSgI \//Lp+j# !A;wu',ONμ&p~.'6XNPv1`ͣ7{˟ֈNp]D!Q^D)z"M Rӄ}ɁabTabau-#"x)eb>  6B@F IH A=L-X>PDe% >0Q6f~ǦIjl@~oA6nRIuT`P o<O*Cq?D~ 8 /CH@%lyA$ ,_ǗSw 0 3@$ɐ@OHPO 900 QEE c0̄3 1^؏/(Dļ#xCwH@CL4>AS 7( L8L .@K %uI,M54ˁQM*; Ga̶/;V"Ӛ Q4`| ?$q! p)]m 8D&.\OP KdP0N&e\LRebAf g,8"(0ԉS =ʐBO\,%#PMp6J|li sV'rS`11<*s3OA)D) DTO M$MEQ5՛[- SX]730uPD^ gNPsJ~MޢX,a}jn8pJpK`{%%l Ҫڄa0}AdU)6EҌtڶ"!,x'dihlc'pmx|+ȤRE >`R:TR6:xL.]x$RFi2A:OffM[%".# y_0a$ y %> v$V``4&c$y %9z2q7#%m4# D2("(|P?+L AWl1mSX/ {,ja@޻&҆5$KK%<t e4ohX30"n0Х4Ц8̄J5[U{. !ky n0vtk~pF7F1 h:!1`lCiC+iN {T#tmm$a(?Y@^lIPJ^l槥B^AR.OG"+ KNwv9,_9_L4!B%E{y P{ NiiYQ*f_<=?̆/"@#]Q#bh0ߎ?d荅@iTZ44=|eJ >^yh̊^&5^ d:pərThYA4,Ѐ{3,&!:\FٚVj4Q`ݢe܄pz1@ZB(Rm뮼ZTAJ, :9B(+']D*J"0+ K<a zo`j[S@d'&,BTWJd)k9G4,&X1,lK0΄| \;_+%@ѯDМTW[eRCs*ì<YVӄ6b#v/Pi@ouW 0P0[69pE 2nَR jm/FKQY8Όpy 7b^:qzo<C-0@0^z_++ '޸k^δ Bsw,G@ "p?K + JJ(s dp ME E\<` P`H( <J³"& ~DP!FHa< C¡0JS q "ZJ,' BL@yNr4(xG {J&;샒8:0᢮ )F4` SDO`GJ``\H2F rQ•Ϋ<2zI.gҊZGr+% j_-A&kaYdcd (o / 0ŝ(@!EH'l*|@@-C 1G@vXgP(t ͐AQ}}8k '%'NvbcA4 "T xi]A 4NrF=4OdRATZF%P E- 3bLoծEXAULjD-ڼڥn;+PtU_S,^ `뗾Vivʏ[1Y/U_A2 IdWšvUSU[֢`"k\;Ҏk- !,x'dihlbtmx|*,+Ȥr1t"(8H`".స'A|2$DНxG2W# &($n%^%f$z%"3$&xz}D"`"G2 "@*"j#߈\e ' $`n$ h @tD(&8"&oYlal(Xhbd4Wt1 Jv2{ CC4uX`' }è!H,"}onNT0JpN JkтPVGem{|#A6@Pwվ,Ab8pp!-b SY@f?8xH^=c_ְWpȀ1ms:zGq ݻw#j|v%NH2AV9,4;Ks gv'YcMJh %DǃJDOcFf1]pކ9bL7c@~'Ţ3/TX X(#taqB6ysJ6_w9ٖDJ1rpV!@RuXdi 4k*fdpKZA9'Q),*3jD%:F: RN^YLfZ` Z6De/B *+*KpjQ&%KR)yTʬdm^i#rN}ke)4+9K3]f`k\O xlBwV1DPw o2w@l0!ӈJg0&2J0)'ql=ɺBkRAEIs;4/H;= u_?;Ӟrb65 7 $ſ|X/($Jοά=w[:@C}ASP/M^,emp.͸,7P5G^lN}=5ٺH]޹$ڿWo}[r\}ް[@9=M d__p? /[18FVb24*SN4zi",dC\ҏic)CC/1=Zߨh 2B_PHQ" 8xdҠ$8-!p ",$ 5p91b#0"`"94` R`9  `er.@"#Ԑ :IG#nQ00*ρI aB! BɇxXv"̈́QD0$r?`E))b@hY`J)ōa5d1N$>6 H'0󇪔}MHJ yXVdM0{<ҙʄ5m#%ȑ8m&ϜI~: `9^Sd 4SuSz?3c`MK/>TbAX_1Wk̫bD0S{P]aC:< ,v3OTc{e썕eb?;u-Ala˂g#k~@!,rr'dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊK H۷n?1,H@A@8.ݻxGE@1 ̹f0FP79\̺kͰ&UƖ_r K0{k-|mƆK2pG ν;gЁj詯TAs_]ߟ^@7)߀L4P w0P| Vx,mwz@s%%I|"zցQ(tֆ3(vD~:9jnB&c[mcEa 嗯%PC晻萀hej.Ħtƣui IzAT6P"@s:*e餘OvjY娤~=4.䫨p<r0f<ߪZ,XΩzHXNF;m^Z:k.~㬫b /8ercBKNb [) Wp6evs1{S{ AlŊL,/6żks L?:,5jԐ'_SO#zt4 ,X58uB+S״ d203Kۤ= tO*k#ߓ2݌ׄcv1Zݸ{C x1ch̠qNh..L# 91L-|#n.&kީ0.8L 3WfP='m* />3#J/f⏥CF$$')J ,  qDX.B5 E#TO,:XBeAQ$ lO5lquO^GHD AGUX!wgr!2I٨dr0i@'O2F)O`er@@ҹ3`J\"GX/`0`)/_l&uY aJs:,byi֒&w k:ʬ39K>#3wax,牋zS:He*"9kq̄'phz* JDj;ٜ-?¢$m%DI1Ҕ*@KPt7oW& _~s2-*o6PSNTӄ( U45O*u j7p@*ȫI%\%ڔjR UtUIdJԄQU#P@):&U4-2A Uk^Y4e힊dݢ)*\uKi޿}g-e #^A\ƐpL3@g}c~.なѨ?HZέؓ06jxms|J <3{N89Wvn`SS`?sG;7>jۡwf>߀ne`t a;EtXfh2rh4%"wbst'#67 ʨG٬h#V/(ڎdH@#39~̄1d`LTΔb/ed"c^B̔en i$fLr9ŜbTУ,D8B‚GXy "f/565ޥ"C)ҳg*}vѧb;VXaH*,Ns\p:HqdIJ>&I_cW UKOh"!$ {P{nBe")цǓ%F=OLZjО@b $EA9FEP=Y(u9EmD.cqCdca4@&hJC$@ ҈ `WDAXX2Ы  k, 2$-l,8YX|p*Q:Ȇ$0/8˂[Cl j TʵiU #QA> M$WUK  0FB"lXx`֑]-*z6C G% ` ù/ 1  ՚"Ѕ [ޖat <ؗ.( Z%/{t%<61bu  ֐K@`I""`#6j_^, ;I%p j/} | o1a @3an.~8/y^BsM814Pi/o̩0S1gX`}ȯ`XTWuI?B{ox\2Z ,RZu{}iZ3{Q;ˎ.l} Ev^mZuo̍tVNt7,r- ^M[;!{&AQ. =pNG_q{#"x!;J(OWqgNkE`~J_8 !,y'dihla3x|@L!A 2l2Q؂جv,$Z<K[ű9inQ x` }hhQr7z|g ~ffsX lʆf W,eث Ʒ ܼl$e_6qXGr~J'B_3ď* =\@0=X+ò濅c6DѦ $8Sϣ\QPs H)5jm)Ҫ4 nkR$6Tvh?a۶nU6B@Ӯ_TleԀÙ4lǚaĐ)&8 Ǒ# (2˙Cc3ТSljհ nuےg~a7͔w(x [7y03-@L: ҷg~]Zvɣw_=Wk`(|I`y_x 6zVu߅7XX淙^(bC=hyeZe~07!S/b:U@aC9&hBT!PwF%Vi%Q%} ԗ `> i(|7^)'3矿?:Mi{3裱N莛ng8YvݙL* { 4Z'jx鮾H4+kHvyճжe0Vjª緢M'Ē[$.l6.n̆lT+-R+(։p G @ / .(0,$l/l1?]KV l8|!u\VpH'ʓ }+mK(bP GTd؂" O<(=d6N~IMG zVQJ F$TB]N@_(#%zK@ '5SPxc+[lQAѷc8%Yx3[e؀Q |fd".SeXí||> !xa.D 9Dr.u=yjaHyN9R(Zw֝d;۔#7䛂G/8v݋[@rFRݺҺu-X-}# =6b]<`zgx5u#=\#O3\Q[Nv`]ljv'lۗk,`휮0k@gfܪ@0XC*Z6Oqs ȸ6g VG7ؖoXݽ)>Y=_>G?߼6B'o"XltLCO1>وn1ù }Na\۾Gl:7+l{_k={ #^݋ǻD_+oy]nߨ|>n|p_rד<7Af>$zuw=gK{?~_>֛^̭{]~c&oC7B/oh#1x ؀ c}8X vx!!,w'dihl릖(Rx-pH,HLh D© *g-4%I.4وRp|n_ oxdN qtXy |~ PYy /RY mwsHZW>- w W {ǯ]*\'`Z1XhkEUmCb, I pOv$@Y˛2"y2M@]3"A~KP> **SNII3fE ׳U=6Q*ڷ<\{'ܻUE+޿q GR?eKQ# K񙲐%k2̛CϪ3SiXڴԪcG#YٱVBmܹ)b83p?q䂗q PiK4p]u[^ꟃUn*_֟ зu _Z&Ƨgfyk!~5݈FՄ(WP]m8 [f@cD?韐<dG$cOǤINV2=QQh GY^x)gWwnVAq)zy#iOZG'2Fziuo#Je:=9+Vo94+6G8~s!=/iQػso~}%t^7:ǯS{G@y.1 e U9Ѓ7ȁRsGxx+E ,7g0̡ސ]~qɟ]`(H&̈́| hVAX c †q(4‡0 (D:шA5xdЎtEQ.k\ , "7v."'3c"HNL.DNzQ*S#7W'zQA0$[2W bni̾-d&3HP 9D^>o39 \+9s5MqZCf8πǰAIM5ps* o"T%P0X84}lIHY',3֟(ELy`H~V؉I !J__xJX zew@H|w^EeIRVo@2-Y^ߜg 5C$ǡ7 8l mB\:\ںF.ʪSޞec=Aۘ42xl`8ß{`$BDV7pD/K-S/EQm6Wf~A!:Qo`7%?uې|Y*K} D6/, (#, oU`1.W sWglۙRW5W:vt\t1z26huZ6]W/a:vE<.2 .:f\[=^w;4#^x$(~{}x2H~݉{R\y4h>q>:y|q><^x[.r=l7׽ _ &~Y寝G|| eӎ7?QA?#~۾~@lf_~:~25W]3ۇ]#Q=ps8Xh؁ "!!,s'dihl분%4x|@E!A4Bbl.GBجvue#(贙SISkwN۹}Kp 6w Jdegm: |f [ƺ 7fʽ"e ֓uG^P]84Ц" @fCƇɎ\YÓ0k eH J).4IĚ@!Y)IYhҩ[*M`e |aKF짌hZANS݋*ֻ, K8X-̸X(nLYUHZ˙H`4 ClԪ{vMLȱo̮Mp8Ç k|0o~yYR/d+ #/.Oz_nz?!_tw߀Ub`m8`U^V rY| GW(_w%4ZX֌9@x+#t&HbcEG6Y,(%'*R\a=w"Z)il:iE`靂1'OvCBy(}(iҳʹI63~vjZR)*^s驽i /Hj+v5Ʈ l@谮 6&@la>S&R۫3f١ܤ H˪:YGBs솦T`oN0q;0-ZQ' l0 @'U ,S[+#0$lO\1)~dLٳt,$ 8{ƱHV>جH\q8h:UX\UmuQx>1גsS99POQ"3î{.Nܻ;m;o<.;a3}=*w2; QϠ;Nǯ= d/3ݹ;ǿn{ghπ< d-g0_7hdr9H) SWKEz듪0 XJvQ K`B"ffn 3 hf(IljSr79$&9 svCd'71x6i}ӝ@6j"g,P{(Fс@h(yv}yt_3, Y_k  X>t$J@A4h#4JǙִ/"`Nie"rp]2ȗA\Z.WGځ~ O;GU:3鴨 GI:OػĬt 'XE|j ZAAMZ=X+BB$*X8F"_cI!vaYrf7XAALFij!X]v]/0ߩ߃s/ҳ1pr:$ܤ6[ʙ Nܼ>e8PtWcB}v.=ͺbv#{z7Q}. \hޑL-W|Ki/K~-IvACr_|zK7mzܓ麯=O> __/+>w4=`}g%o}nup~_A_>-.Ne'~'1 ؀ X~'Px Cy Ё "8$Hw}%*$.0284X!,k|'dihl뢖(8^KJpH,H hJXXj(4)ݡ&ϘI>Fؚxi)sa]:i;*hmz 諷9M"y7f+\J#jάf+46*oBC M^ ,8;XEsxw?βHEp/QtR^q/G, [7nǽ:<$<2lb4l3(pqƓ ;%7m9@ e"qC$Ko"*BS8H\ےƥF¥b સFtaFa+wEOLOA,5 p} aֺ x%" JV DuVaEWڵ !Wt aƦIl ӢI ȡHPi!Gj"Z֬*y"pc+ +#Cn#BЭ+$zB.$RATg4-xW#}v'E<%` K?~ɼ ԛ@pO@pv)_Ҷ6S xANYa '`kC&1 HܽMs ,9zv5T+6F'a3ICF\z+l-')xV̞Bl<:܋ *C;g 14;8£O<#K@5Zƨ`W̱k J}:2 Q=q+s9#_jL9/ph}:0*|wl Ҧ i4++bl#;֣5G1X ^Z>ni_ QЈP|V`AQNBEqm-}n-3|5 `C%oP>z Z:̍㉸[q@~oϺ榓9ӇOacwZzz~G_zkO UWtrX _y' P[ `bFWtz| pWDVۄ*ʼ[V 8 AY)= KHQ:i3@Uŏ +4d@Uɗ+HLf-#a4ҦO \|qϣpP2P&TQ&Z&p2i]ҳŜeKאp][ BBPůM Հ[.eO$OTCd7Ct6fVng[l{ aDS%BSes B6䨹{m*.Y9z׳o`:z~O|~qA'HT {߂ '~Fsd{)!6! jg|,vh+Xށhy V%]^:݌yh. VXPXWV_턡]9`"cUO0Qb4U`_Iiҙ\m¨e 49TgIn&N~$Z֥C_f*5l ViIY ݦtj{$2ufjIJM  j,d#벆!Э;Zm{>D涐;Pw8[\JFƻVtH/PH,lRWl[,JA~͆l]0p*&m C5E<hL354s>Ft:7+ u_T\`hw  _+ %ut]lk6zm߀kvM5$on6 勻<,E^47q/7ta5,謨s@鰛^MS.D&.VZ=zhX9TSfBP#SDHǞq0G)"Bs ;AC:b*>;ieKbBF'4PDDSrvQHeZW!e-_Y`od@UbRL210$ \f34FK`kb7 pp4k2 lg49qs=9isl=O}g@XE 490E/[X/0uڤ@ )<"VY Yu>rmBCa:#L!H8)-;ר9a?m;k1*Nd\Z o6Q~+I |фY,>ˆagu*<9ĠJM4w|5{@"/k&A:TmCXʢa.-x 뎈k@ߚ?Βr?U.FKB8 fmTږ؅zw:7 5& EYx_75_T |W #Ja Xp`$a%u/K?3nZJL*$ Bb!8{%GPmn-{ "Bd]nx"$ 2 ʬ;/K%<K@L=Ov^ޅ3@ )yvg\\2C8] WԖ&$#̐KG ҩ P#ui:w&*vk(Tnagc (|>%l@#|4 Z2F4 }H a#{kp慿,< >´akq_.i n3p%q/KWq3 MAFPǵ7Y}cJµWF71]jc9q@AOI/̵]Qqx@:`bg3i'"=R6;S]ź˜W6.xç`vԋxǷ|ފq-_y yC;5~գgq]`jlo>$|ݠnֻ/GN=e v_o᷀}Ng 6~/d}gO>??/~kyvxGtd=L8XX؁(g"8$X&x( f)؂.%284X6x8:<؃>@B8DXFxHJL؄NPA!,N['dihl뚖HMxSK E,Ȥrl,[!pجvT,贚HPئ.gNW7n UzxyX_ d#9qXZ HY vjsX I ̝C&ź  8Z9D@kJW@ËM82H}<ԶO˛PI/ ΗS˜͟!cSHҴ/ jk/, iS׳9Rh2-.TҢ][ _T'^\\Ô,ldLY Ń$+3cIcc~ lٸ9ЮܕVxnu8nlP9pb sW~}wx;G~~\sDW7|խۏyGtP~V4u'q ޅVha๶Y_1"*a3@vvɘcy#y񨕏CWcT,&I$vwKX:Xv dTI|Q!ilTI8Y/I 9杫 `FW!$)hhIGCeFa$qi)n禋YR9@ij諌Qv!>: 1+개άE6[(zmᶥؐ'Y%A&+ocl8K|p,p;TaE9 uWlc 0#|,Ag_f숅8C?2e4cRBS3 9XYsA=ᒙ &v$wH2_=>2)%#x^^bV?a1I1dDdBhF3fL$#7o g6'9͉tNkbᬧ5yws49lʓ7wsC!2P`xNblZe_BGn`6xȈc\WѠ!Sdx*Ņ?F1$qMSQM;md^aE(|*é惬(+ i"կ:K}bb'z quty%\1T6a"3"1\,ˮ!(}Ŀ"'eHD~*2-x?;<@+?{>AM㐨k>:˽:ծVY =!8$йm/|!ռK@;"϶N~'^1x}xɿ|AD&|0vDp"s/ h@L/\T.gS.#E йZ}CŽJGp1[,a2\[oϻGX/px~fhddQRu&ޝIPF΋yw$DL+а1 = J>*bAS+t@kly.K  v88t~924 .MB (A5B 8 4QH[6Y Hp$~ZQxJ!6~ݷa 15.@N¯5o:{s>Cs0w]]|A,n]{ vhf* (wİqUq" `4A|PHA9sCn6}sNzp"Qzֱ=s sj_;xnEߝOzi- i#[-|qo{n|HO7Nj@˻O@?_#ҟ>s}~@w-/~@ecy?~gMw?WgXr'WCا~+e҇Kc}o'8|B^7O "8$X&X(|p,؂.X 284X6x8:<؃>@B8DXFxHJL؄!,GS'dihl떄HEwSK kH,Ȥr$lDXlS|asL.蔅֘V|Nǵ݄/e4QoVvwW]{kmW_D oz mt  grV C Ǽb"Vz f .O/P6!1" EܘX_C(lDd_ xWfU`sɅ|BryXwz% H4 X385sHSCJ&ٝQxAЈX#=Hvܒ 5)fYߙV7am!)'vi&iQ|ZFBX(x(v;E⢥棐 7vVZ(n#姹I 'B6h=WꙖde笭Ψf4jdvӪ^ ʩ46kX )'#ֵsͭBV7E&&0p`W,4{L  7G&cS0Wۋ,WƫTp$,3cz2N @3QsWƢ*3  P|@14Dzt\wrFouu4Y^IRI'x7<5R-0y6n/osӆG^ލ36N9LP-Cyⱌ~ل.ݪGDƙ#S{NǛ*xOm;KN#/=֎/SAw6 x:ާ|{+MslW:DKdz&>]\gFur_'z= zjcJ=@(7L @⹯CgCPbU8"Bm ?#:f \:X jiY f#уYu1%o|Hǐ3X>2lvS4G?d?BrB2+8d^ >%O7cWfM lK1@$ 0}i`s y13 g#M&(YdSe: i,4)h~S @7 Ofg=L@sd,M<=mbZ2|{&&kv!PWEA)PQԐ`?3% 16tp'F n\@fqoU3^:ØFlWZ'ŢT0:3}"(6iG+W`jFՈ:=Z{8֕NlO$j*Cjwm*F0Kn`@0>-3bX"q?LdPY ~@Dlj^[YjB\I+=BZ qEUWLEMUPFpSb)-K& lz?&gElP\ S Kp9{CrޙLn[`_WN`t]P]Iv]"ӷ`ty`@zǛ0 F<L* Mp'@U%>y7WJ.K k r O(D CgE1Oc,yvm&F̜f\ObV_If%#u >2>&@% d* ޳t W)0t= ӏ+`ǣyfB' D-9D`n[՞Ҽ{g 3B#"6P]S$pWi,vx` c,LŶ9fɑ펜a+So"'! 4hZ`   >]^8hS 8J<| |fwᔐ hP\0W@֝?Mo@ܽΗl~y3n(W6ǻpԖ:u`{mZ?C 0aGIߵi7ٹf-q/ߞ yVw>Ft} te{>ˎWQyl<$6gQ>+ װ|z7A]ozWhݽz{D1OsMgڏo}} =?u~"lj2_g~}#_WWie74']W|8308XxP {t؁hPM0$X&x(*4W| 02wx8:<؃>@B8Dw!!,CN'dihl랖Hb7xXpH,Ȥr)"B!p8vT*BczU,J\7!F(lfnQ rYwu[`c SZBZ zip͐z.rr " Yʾ Gp [HHȰb7Eܨ eIIZ\)R@'cPP˛0y2B@ey3"MAY ŸJ@cSk]_j*igfNvW Ylnߢ )z &礁G>v ՜)jsx詚i'5ۖi+p5Zcꮞ::f8٬dS볙j:1f+ڏHpRUv,5R:lyt5~|HqRHQڈ1f D,W<1JE1-0lcV[Ƿ|F08+e#sWz|H'}2,#W<:3|@Xg]-55HmU_h_ p/OzK./dim7qe1p=݀>č-т78Ϭn۷SV?ykK 4lnLjF6.;$rz x s* 7C?~@ J`G^@TS}ϼՠ{Qt~1 |Xk=u_ =u-9c~LwmcZ'lr3KG ZV3}k7. h_G郡¼CW(5-Łc\\G&f͂@5\::[^E0$X ɴ ABh@HoCHGq3HȬX>V J&% Tnd8d| ̤#q exVh:2W$\Zn@+mI4yS 27`L$s@3AeJS@5ɀ| %93.̉jNl5xVs`=Ks<) p,h8ɉRe &eAŹnfa@EB#эs^`E%PK8kcBhVHf)+h񠕸kGԕtAwj'!VŪoX #RL1ZO13m kǪpmj6񬹁z}.#޵y\kjÚZڥ {ǾP l R R, 9[Ik*J9Z!kWv@w]F,-~ {BvUޮr;Aڶ;&_ g$IuU~qWUzU|'`NT`^ lvnn[  ޳\?|l@hLsVcT@N[dQ6OU^ߒKp;(-RE.})^aMVЀ(k%$GybPNӦ6[Yޜ[:;9_qx̖VAuڝH*H4|gmS1yv6AMGf!W2U)eW!_g @2 Jhb=}i8.qAn'"o@Sa(C*;rö ^(cAr.{suv]6Pj]~ts$]t$(=pI>Vϩ٣^ֹnk9fN d:ۉUȓ܅PwK~'_{'8zEn挊VF&>KF]li颇v馌aΣZ70#~Z`骪MF8>jkjR鯫 r&k0&[lcF*L,)v[ٷ+n2}ql+ SA{q1(*+ G,K ;AKJr/Wl(OR!e^ 7|@)笳+1^1\0O57H'r.(3_UJWm5,_BsD+7_-)PU+Eb4pm2Mcv0l$GTc\Rs}7u,43.8ډM}tMx 5x7~:JO9|ǮtT{( S8WÏnr#KC}8r;Oۗଯ.3ON?2dcw,>tKIFTȡ;?mxp&AIu#ERAn!8 Wp`Oƾi8`(E[h @&^M|`>U@'Z1is`T`AX* w@E0yHHGHmX>̈wآ,X8&'"@5䑑d&i) PԤ('Y)e)+2hZJ ~^iKQV" `/kɀ`@1B1\&> MdQ`3kCL&0yNn3l'4) pĦ(yOnsg8x 6*q"X@р,lgAFM^P/싣aL($ Ik+JIF~Zq{KCͧ\J`Rr`FqL:.->0+l@jmZޛ2tWTRHV4SMT8U_iھHĥ.W̫sľ2/ xC"MxiB&&|Cᮝcw(ٶ`S f)T[lKUpUT.P'uyVn;W =lk-n%DHn%U{-"- [鲩 rk]ʽp =7zQ]n ݪ  I!`~) =xP4@x% g8vK2O#H&!:$Mc KʻӧKҪ"94 XB|S!䵕BXOJ=4S'o2o_KX0ɀ˱˳~($)C(s[IoO&B%Bѥ3mS=0et|q j԰F8T5L }N`K˙Evm CP8öxNB-N d (uν:>Cla oD v%ay׎5$d[l] y;85@@3FČGi7.)Clo1T9Do=eXyqJyg|C=R7:w7_] \[_] d[]N6 M77=#Y5 ^L(3#7Tnx"^ n_^,o]cC<=y$lspS?y#_[{ݞZ/[W7f'[ϫ7pܫo,jڟ4W-?O`~_{_z@p?z_cW|Kykֵ ؀8|X~H% "8$X&h',؂%028!,?I'dihl랖Hb#MXpH,ȤrID,ZvrL.h!j\p8gPTYsp _a Q[ DS[XW{dvqW B nڸ " lW LcA<uc7kJ&Ë D1ە0DQVǓ1)RB~(c.KȂVd,͆.a+]ȟ$TY/HY(UUWFdn׳zANprVfԠy #@_?+N[`2 ^.H@h"LcG4s*gCD^M4j$$k"iRm4^ Ó72?!uMNuvsmt<},uݳ^~H|G^bY (`]Fؠw~g!U݆U R`[Ah{c{X K.`oH#w6D^wE%&Y$K:鞈#i(%(6Tb\*7a>&F:؎l֗;CY_湳ܹ |7'8ed1#rG%>6[4)X0ߥΞv4Xj*m}S窳y͢&7`ֺߨ”+g~ ̫0%˪À,i~ƒ9͵l4v+X +b cuR(T`o#{oNa/6f4hG G,G Qi$- P$L1RW2)0&lB;˖\7m4ڂ`>`2|T|΂^][`)qih"rl]׬,?3zU/CK|oDM%u߈#~qM  Cw8v'~NM?ιDz壣frS륓<`Ű:C<~p4cԳ~MBNL|^pLnQ{{|?r.ݳo0 GJ*J@PڜP6_sGà&>̽\KW6-~" },,G_NHZ WXLz8U!{ᘟH)2DFX68F7qdB<a.o $:#3ȕ;2T?b# K2ǐ4cSj+3HpHe\bp@b`yJď&dA^FXV0kٜ2cJc,3tjSf;]NYs'>iYsެg(yʜ `QBFYSd26E`-CyuB2 DDxb/fjCd?aC-0).8M2ӎ#Sza8"qX/7A3MHغSJqX_V[3m|AC#NA)N1}c~;qBv|U0_&UV@?35Qlͪ[VA$TJ'al#$Nj]6DA\"ڵ+~ PS/榞  %BkIh;q>ȠP1Epn4&ŵٗo,} @;~ jI[y)"t9]r%oQ}1^>vQ9*1ȼm:H^$m9>ۯRrǩ~V8tՁ}@<=lD_==Lhw+zݫW wVx#nO oA<,oσ^煌ӧ 譼fz{Y }jotz{_]>G`6#+|+?ͧ}kO۷~}|?_>}Wg?>n|o{89XxzՔhDXx8~Ɓ "X&xG!,>H'dihl뚖"IxXpH,$BkJ#Z*G(rL.hb9|NV 8ckOnZtrWw lVVw a/ Z {uUe nsZ*p UTg4xt*{e{uv߀]!{k)ؗynZeRIa,hS#V"^)ԠԌ8nE-"(d?DGW5a(%u-$*V7҄^4´BҐOF>#dYY&|2|X$Ag#L%$5rGR|g1<@!_Sؘ4c:GbGB f5ɀuds7,rnw`9hLsۼ&1 xg8kN}x?)ORs$E?OeA.)p җ6XPI8FOko=GZkDfL>P-thhI{/WQnxoZsfjPjѨ1P$䔉PUX(T2T 5k MM3XMR34GU1XN< U#bq"5yP3X$\EsX#3X ^g ξb~IJmʶ.B; .ֺ$F;bfׁud|hnzGHX6y /;o(?K&:X84!V0 >Kv.*aX{e12&Hې"&ՐAً~=ery-2eXˇd8*R&oGNd%]3,)9ZCq'(:e7Y@p i3'`Ht>_㲀 ӃsD W:a4 mdDgF#CϺn9:%yㆭl=ږtX?-Cd ~[A("n;3^''Q`r-4(˂37njY1 j@ 74>\w&O^=o,:ޜo9~{wamt+=?]c;?Q[_N_w_;y \wmꮃD֣s;-n'aawaTn9Za#?5?~7_9_|!]|H_ өX:]D}Y@v߽ zW폟|$q|<g~9Su}/`g/{_/086Xxx:z8Xx|̔ hu$X%!,=G'dihl몖(Rms|pH$FhV44%B xL>ɒ GnpXnyHitoS@mV [^| LkuR|l.mQy"B # f 'ݳ +* bo. yX(]@\cZA="HQq*PFb$9ǚ[FSPL!'̅˝>v:kMCN:B*IL)0/꣞O]pV`Z!Nι<.Ż*| XG^Ha*Ą<^D$caYf!)tўM7+,:h0 +ɾ=p Ki,(_]+!덾_)k0`3@l3s/Df8t{| Cry/J?{qmQ ZΓ3LE~!@~O;㡟.*(@x؍wX^7?zv) ~[3؇ZHУbq9JB!  6z:V0;h(0Sᨶ(ꏁJȤ 0UpcD @A Ӥ4QH N|FDh\c"X ׀ ~9epI,`Eh3 DVGB$2^6 = (m!PhPuAh=R")DZq G5 ]D%&-TON-BT1Ӑ֧?8j= SX9B'65YUI= įψ+x (#BZ_Sr,TG*ZðweHdɁTvhTH$JQa\qZE啱{F]+5X6,BCIbr-fاjғh62Vqiw5">LBgPdEw@ԛ5V@O ৽ ̋W}-悷)@| &7,l(0 e2îH)@10Pt*@H~PXPs bx@R? @ƿ 4JI-dՅ,,u2eOdFݸkpqg!94t: D`Xv(<:+Yw]EJ ƢHƫ`Z!f i&cťEfH«ßEG}4%@G6~(^^ۨö-]4A vkI "=cIXre[ȷ .i˚Bb>#  ;N0|7$- ?p0Ԙ`$u, \&/숟_䛉,0l|?.C^.U@E!Qdz(-!5Ɲ3tY;Fg],gjw! ;!;Qnu#v{#Ug*'>?yk~3&ENqЗݓz˷гOO;u<'}<苏?"?=fCw!@ܗ3W\Cc "xr!,=G'dihl뢖Hb8B+JpH,HYQH$>G@ZJ(|:I.4K`&1 ݏDh Mq"sgu#Y `|mo"q^c+M( 'A (#͸٪u+[~?[f?.A( |Gg2,42'!0ŋ" Hf},q+%MvT*HI`BOMu(+RsgOt %25BsS_>:XGYU) H,ٳi̢]KF-۷D#*WxIH}Q^<*3o}|(É/ AJp ̤zN/뼊_ϝ,[M(kI{u,hM#W#*7Իή&Rh,cOùjLٰGCPF0fG 16EHH8QpxFdA\/HF{,HHƄlg*2SDp ,Y@g?גHՉP/MV9ϐW%H$"k %,:•V',Yޣ\4裎~hP0'BR(9qdQAl poXx N*V '1g"k3Rkk6qP Ǭj-8\­c[4;IK"PR.'w$HKߪ츪,l)uPrv9.W*2ǁ ?l\Jh||@X\O ) qΙas~4a?b1e1i+s_&BȅL}@fF,-Hl*Be`ᰡ"%14/ ?U(}*"1\i#X>qv*c3@:Z6.M0[ĭJ2d0K-0=يfm:3tGtG84g8yH I6>{PrSD?ڌij(gԉ{k$ۘ'I)% ܙT@E0Qm6B?6,ŋ%iIT !(.0u'jT@j Pft XUXaU B@yrF]WP"p4gMZSmd E'1t(*$Ğq@1Wt_%AAJQ`/ZQEpÿCkZkey=ЄnSP64uk=얷]x+dFtǬ2/ 纖h+8^I׉O}KUZ"A`0+]S0`NX/'xa41}CЗ$V/3Ll^64@d=''TCpL8E6 'd_DY0So_TWLXt[6so /"}aܜ334s^:_}8@BЈNh:x"'}hδ7N{ӟo^@MR!,!,!,O'dihhp,tmx|pH,Ȥrl:ШtJZvzxL.zn|N~Ðew?"ܫݚ}@^Hkš-t #YX+ċ3jȱǏ CIɓ !,VJ'dihl뾤tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~+ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S;\ɲW0cʜI͛8)ɳϟ@ JѣH*]ʴӧPJJիXj!!,!,!,QJ'dihl뾩tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~T H*\ȰÇ#Jpŋ3jQ CIɓ(S \W!!,!,!,!,!,!,!,=G'dihlI"!x|pH,H_EH:Ш&5جv\rxL.zY|>~[m-#6fvt^ÏQн壃) Hr*\Ȱ!~#JHŋ31RBG r31(d/%O"d a9+ip3@%+>h 0Th$z9@cЫbO\\ dsжU;YKw*/cL2c3ĐYLe3ϠCMLҨS^m3װ1$e?b@-ׅt&apptz٩[rϻ7<+?Ͼei'=MK?}1*޷I&Bg=BؔS-vdv ($h(y!X*(4h8ȉZ!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,!,;