8889841cinc/Helpers/Util.php000064400000011225150515074560010356 0ustar00 $is_facebook_installed, 'is_instagram_installed' => $is_instagram_installed, 'is_twitter_installed' => $is_twitter_installed, 'is_youtube_installed' => $is_youtube_installed, 'is_social_wall_installed' => $is_social_wall_installed, 'is_uncanny_automator_installed' => $is_uncanny_automator_installed, 'facebook_plugin' => $facebook_plugin, 'instagram_plugin' => $instagram_plugin, 'twitter_plugin' => $twitter_plugin, 'youtube_plugin' => $youtube_plugin, 'social_wall_plugin' => $social_wall_plugin, 'uncanny_automator_plugin' => $uncanny_automator_plugin, 'uncanny_automator_download_plugin' => $uncanny_automator_download_plugin, 'installed_plugins' => $installed_plugins, ); } /** * Get a valid timestamp to avoid Year 2038 problem. * * @param mixed $timestamp * @return int */ public static function get_valid_timestamp( $timestamp ) { // check if timestamp is negative and set to maximum value if ( $timestamp < 0 ) { $timestamp = 2147483647; } if( is_numeric( $timestamp ) ) { $timestamp = (int) $timestamp; return $timestamp; } $new_timestamp = new \DateTime( $timestamp ); $year = $new_timestamp->format( 'Y' ); if ( (int) $year >= 2038 ) { $new_timestamp->setDate( 2037, 12, 30 )->setTime( 00, 00, 00 ); $timestamp = $new_timestamp->getTimestamp(); } else { $timestamp = strtotime( $timestamp ); } return $timestamp; } }inc/Helpers/SB_Instagram_Tracking.php000064400000027053150515074560013602 0ustar00Name; $data['themeversion'] = $theme_data->Version; $data['settings'] = array(); $data['pro'] = (int) sbi_is_pro_version(); $data['sites'] = $count_b; $data['usagetracking'] = get_option( 'sbi_usage_tracking_config', false ); $num_users = function_exists( 'count_users' ) ? count_users() : 'Not Set'; $data['usercount'] = is_array( $num_users ) ? $num_users['total_users'] : 1; $data['timezoneoffset'] = date( 'P' ); $settings_to_send = array(); $raw_settings = get_option( 'sb_instagram_settings', array() ); $feeds = SBI_Db::feeds_query(); $feed_settings = []; if ( ! empty( $feeds ) ) { //recursive json decode $feed_settings = array_map( static function($item) { return json_decode($item, true); }, json_decode($feeds[0]['settings'], true)); //map array values to key => value pairs in the $feed_settings array array_walk($feed_settings, static function($value, $key) use(&$feed_settings) { if(is_array($value)) { unset($feed_settings[$key]); foreach($value as $value_key => $value_item) { $feed_settings[$key . '_' . $value_key] = $value_item; } } }, []); } $settings_to_send = array_merge($settings_to_send, $feed_settings); $con_bus_accounts = 0; $recently_searched_hashtags = 0; $access_tokens_tried = array(); $sources = SBI_Db::source_query(); if ( !empty($sources) ) { $sources = SBI_Source::convert_sources_to_connected_accounts( $sources ); foreach ( $sources as $source ) { if ( isset( $source['account_type'] ) && $source['account_type'] === 'business' ) { $con_bus_accounts++; $source['type'] = $source['account_type']; if ( ! in_array( $source['access_token'], $access_tokens_tried, true ) && class_exists( 'SB_Instagram_API_Connect' ) ) { $access_tokens_tried[] = $source['access_token']; $connection = new \SB_Instagram_API_Connect( $source, 'recently_searched_hashtags', array( 'hashtag' => '' ) ); $connection->connect(); $recently_searched_data = ! $connection->is_wp_error() ? $connection->get_data() : false; $num_hashatags_searched = $recently_searched_data && isset( $recently_searched_data ) && ! isset( $recently_searched_data['data'] ) && is_array( $recently_searched_data ) ? count( $recently_searched_data ) : 0; $recently_searched_hashtags = $recently_searched_hashtags + $num_hashatags_searched; } } } } $settings_to_send['business_accounts'] = $con_bus_accounts; $settings_to_send['recently_searched_hashtags'] = $recently_searched_hashtags; $sbi_cache = new \SB_Instagram_Cache(null); $settings_to_send['num_found_feed_caches'] = (int)$sbi_cache->get_cache_count(); $settings_to_send['recently_requested_caches'] = (int)$sbi_cache->get_cache_count(true); $settings_to_send['custom_header_template'] = '' !== locate_template( 'sbi/header.php', false, false ) ? 1 : 0; $settings_to_send['custom_header_boxed_template'] = '' !== locate_template( 'sbi/header-boxed.php', false, false ) ? 1 : 0; $settings_to_send['custom_header_generic_template'] = '' !== locate_template( 'sbi/header-generic.php', false, false ) ? 1 : 0; $settings_to_send['custom_item_template'] = '' !== locate_template( 'sbi/item.php', false, false ) ? 1 : 0; $settings_to_send['custom_footer_template'] = '' !== locate_template( 'sbi/footer.php', false, false ) ? 1 : 0; $settings_to_send['custom_feed_template'] = '' !== locate_template( 'sbi/feed.php', false, false ) ? 1 : 0; $settings_to_send['num_found_feeds'] = count($feeds); $sbi_current_white_names = get_option( 'sb_instagram_white_list_names', array() ); if ( empty( $sbi_current_white_names ) ) { $settings_to_send['num_white_lists'] = 0; } else { $settings_to_send['num_white_lists'] = count( $sbi_current_white_names ); } $data['settings'] = $settings_to_send; // Retrieve current plugin information if ( ! function_exists( 'get_plugins' ) ) { include ABSPATH . '/wp-admin/includes/plugin.php'; } $plugins = get_plugins(); $active_plugins = get_option( 'active_plugins', array() ); $plugins_to_send = array(); foreach ( $plugins as $plugin_path => $plugin ) { // If the plugin isn't active, don't show it. if ( ! in_array( $plugin_path, $active_plugins ) ) { continue; } $plugins_to_send[] = $plugin['Name']; } $data['active_plugins'] = $plugins_to_send; $data['locale'] = get_locale(); return $data; } public function send_checkin( $override = false, $ignore_last_checkin = false ) { $home_url = trailingslashit( home_url() ); if ( strpos( $home_url, 'smashballoon.com' ) !== false ) { return false; } if ( ! $this->tracking_allowed() && ! $override ) { return false; } // Send a maximum of once per week $usage_tracking = get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => sbi_is_pro_version(), ) ); if ( is_numeric( $usage_tracking['last_send'] ) && $usage_tracking['last_send'] > strtotime( '-1 week' ) && ! $ignore_last_checkin ) { return false; } $request = wp_remote_post( 'https://usage.smashballoon.com/v1/checkin/', array( 'method' => 'POST', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.1', 'blocking' => false, 'body' => $this->get_data(), 'user-agent' => 'MI/' . SBIVER . '; ' . get_bloginfo( 'url' ), ) ); // If we have completed successfully, recheck in 1 week $usage_tracking['last_send'] = time(); update_option( 'sbi_usage_tracking', $usage_tracking, false ); return true; } private function tracking_allowed() { $usage_tracking = get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => sbi_is_pro_version(), ) ); $tracking_allowed = isset( $usage_tracking['enabled'] ) ? $usage_tracking['enabled'] : sbi_is_pro_version(); return $tracking_allowed; } public function schedule_send() { if ( ! wp_next_scheduled( 'sbi_usage_tracking_cron' ) ) { $tracking = array(); $tracking['day'] = rand( 0, 6 ); $tracking['hour'] = rand( 0, 23 ); $tracking['minute'] = rand( 0, 59 ); $tracking['second'] = rand( 0, 59 ); $tracking['offset'] = ( $tracking['day'] * DAY_IN_SECONDS ) + ( $tracking['hour'] * HOUR_IN_SECONDS ) + ( $tracking['minute'] * MINUTE_IN_SECONDS ) + $tracking['second']; $last_sunday = strtotime( 'next sunday' ) - ( 7 * DAY_IN_SECONDS ); if ( ( $last_sunday + $tracking['offset'] ) > time() + 6 * HOUR_IN_SECONDS ) { $tracking['initsend'] = $last_sunday + $tracking['offset']; } else { $tracking['initsend'] = strtotime( 'next sunday' ) + $tracking['offset']; } wp_schedule_event( $tracking['initsend'], 'weekly', 'sbi_usage_tracking_cron' ); update_option( 'sbi_usage_tracking_config', $tracking ); } } public function add_schedules( $schedules = array() ) { // Adds once weekly to the existing schedules. $schedules['weekly'] = array( 'interval' => 604800, 'display' => __( 'Once Weekly', 'instagram-feed' ), ); return $schedules; } } inc/admin/class-sbi-account-connector.php000064400000022111150515074560014425 0ustar00account_data = array(); } /** * When connecting accounts, modals are launched for various parts of the * sequence * * @param $sb_instagram_user_id string * * @since 5.10 */ public static function maybe_launch_modals( $sb_instagram_user_id ) { if ( ! empty( $_POST ) ) { return; } $connected_accounts = self::stored_connected_accounts(); if ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_graph_api'] ) ) { sbi_get_business_account_connection_modal( $sb_instagram_user_id ); } elseif ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_account_type'] ) ) { sbi_get_personal_connection_modal( $connected_accounts ); } } /** * @return int * * @since 5.10 */ public function get_id() { return $this->id; } /** * @return array * * @since 5.10 */ public function get_account_data() { return $this->account_data; } /** * Get API data for the connected account using the account access * token and ID * * @param $data array * * @return array * * @since 5.10 */ public function fetch( $data ) { if ( ! isset( $data['user_id'] ) ) { $return = array( 'error' => '
' . esc_html__( 'Error connecting to Instagram', 'instagram-feed' ) . '
' . esc_html__( 'Invalid account ID', 'instagram-feed' ) . '
' ); return $return; } if ( ! isset( $data['access_token'] ) ) { $return = array( 'error' => '
' . esc_html__( 'Error connecting to Instagram', 'instagram-feed' ) . '
' . esc_html__( 'Invalid access token', 'instagram-feed' ) . '
' ); return $return; } $connection = new SB_Instagram_API_Connect( $data, 'header', array() ); $connection->connect(); if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $new_data = $connection->get_data(); if ( $data['type'] === 'basic' ) { $basic_account_access_token_connect = new SB_Instagram_API_Connect( $data, 'access_token', array() ); $basic_account_access_token_connect->connect(); $token_data = $basic_account_access_token_connect->get_data(); if ( ! $basic_account_access_token_connect->is_wp_error() && ! $basic_account_access_token_connect->is_instagram_error() ) { $expires_in = $token_data['expires_in']; $expires_timestamp = time() + $expires_in; } else { $expires_timestamp = time() + 60 * DAY_IN_SECONDS; } $new_connected_account = array( 'access_token' => $data['access_token'], 'account_type' => 'personal', 'user_id' => $new_data['id'], 'username' => $new_data['username'], 'expires_timestamp' => $expires_timestamp, 'type' => 'basic', 'profile_picture' => '', ); $refresher = new SB_Instagram_Token_Refresher( $new_connected_account ); $refresher->attempt_token_refresh(); if ( $refresher->get_last_error_code() === 10 ) { $new_connected_account['private'] = true; } } else { $new_connected_account = array( 'access_token' => $data['access_token'], 'id' => $new_data['id'], 'username' => $new_data['username'], 'type' => 'business', 'is_valid' => true, 'last_checked' => time(), 'profile_picture' => $new_data['profile_picture_url'], ); } return $new_connected_account; } else { if ( $connection->is_wp_error() ) { $error = $connection->get_wp_error(); } else { $error = $connection->get_data(); } $return = array( 'error' => '
' . esc_html__( 'Error connecting to Instagram', 'instagram-feed' ) . '
' . wp_kses_post( sbi_formatted_error( $error ) ) . '
' ); return $return; } } /** * Add data to current set of information about the account * being connected * * @param $data array * * @return bool * * @since 5.10 */ public function add_account_data( $data ) { $data['id'] = isset( $data['id'] ) ? $data['id'] : $data['user_id']; if ( ! isset( $data['id'] ) ) { return false; } if ( ! isset( $data['access_token'] ) ) { return false; } $access_token = isset( $data['access_token'] ) ? $data['access_token'] : ''; $page_access_token = isset( $data['page_access_token'] ) ? $data['page_access_token'] : ''; $username = isset( $data['username'] ) ? $data['username'] : ''; $name = isset( $data['name'] ) ? $data['name'] : ''; $profile_picture = isset( $data['profile_picture_url'] ) ? $data['profile_picture_url'] : ''; if ( empty( $profile_picture ) ) { $profile_picture = isset( $data['profile_picture'] ) ? $data['profile_picture'] : ''; } $user_id = isset( $data['id'] ) ? $data['id'] : ''; $type = isset( $data['type'] ) ? $data['type'] : 'basic'; $account_type = isset( $data['account_type'] ) ? $data['account_type'] : 'business'; $this->id = $user_id; $this->account_data = array( 'access_token' => $access_token, 'user_id' => $user_id, 'username' => $username, 'is_valid' => true, 'last_checked' => time(), 'type' => $type, 'account_type' => $account_type, 'profile_picture' => '', ); if ( $type === 'business' ) { $this->account_data['use_tagged'] = '1'; $this->account_data['name'] = sbi_sanitize_emoji( $name ); $this->account_data['profile_picture'] = $profile_picture; $this->account_data['local_avatar_url'] = SB_Instagram_Connected_Account::maybe_local_avatar( $username, $profile_picture ); $this->account_data['page_access_token'] = $page_access_token; } if ( isset( $data['expires_timestamp'] ) ) { $this->account_data['expires_timestamp'] = $data['expires_timestamp']; } return true; } /** * Save data for new or existing connected account * * @return bool * * @since 5.10 */ public function update_stored_account() { if ( ! empty( $this->account_data ) ) { $single_source = InstagramFeed\Builder\SBI_Source::update_single_source( $this->get_account_data(), false ); return true; } return false; } /** * Actions after updating or connecting an account * * @since 5.10 */ public function after_update() { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->remove_connected_account_error( $this->account_data ); $sb_instagram_posts_manager->add_action_log( 'Connection or updating account ' . $this->account_data['username'] ); do_action( 'sbi_account_connector_after_update', $this->account_data ); } /** * @return array * * @since 5.10 */ public static function stored_connected_accounts() { $connected_accounts = \InstagramFeed\Builder\SBI_Feed_Builder::get_source_list(); return $connected_accounts; } } inc/admin/class-sbi-notifications.php000064400000062631150515074560013665 0ustar00hooks(); } /** * Use this function to get the option name to allow * inheritance for the New_User class * * @return string */ public function option_name() { return self::OPTION_NAME; } /** * Use this function to get the source URL to allow * inheritance for the New_User class * * @return string */ public function source_url() { return self::SOURCE_URL; } /** * Register hooks. * * @since 2.6/5.9 */ public function hooks() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueues' ) ); add_action( 'sbi_admin_notices', array( $this, 'output' ) ); // on cron. Once a week? add_action( 'sbi_notification_update', array( $this, 'update' ) ); add_action( 'wp_ajax_sbi_dashboard_notification_dismiss', array( $this, 'dismiss' ) ); } /** * Check if user has access and is enabled. * * @since 2.6/5.9 * * @return bool */ public function has_access() { $access = false; if ( current_user_can( 'manage_instagram_feed_options' ) ) { $access = true; } return apply_filters( 'sbi_admin_notifications_has_access', $access ); } /** * Get option value. * * @since 2.6/5.9 * * @param bool $cache Reference property cache if available. * * @return array */ public function get_option( $cache = true ) { if ( $this->option && $cache ) { return $this->option; } $option = get_option( $this->option_name(), array() ); $this->option = array( 'update' => ! empty( $option['update'] ) ? $option['update'] : 0, 'events' => ! empty( $option['events'] ) ? $option['events'] : array(), 'feed' => ! empty( $option['feed'] ) ? $option['feed'] : array(), 'dismissed' => ! empty( $option['dismissed'] ) ? $option['dismissed'] : array(), ); return $this->option; } /** * Fetch notifications from feed. * * @since 2.6/5.9 * * @return array */ public function fetch_feed() { $res = wp_remote_get( $this->source_url() ); if ( is_wp_error( $res ) ) { return array(); } $body = wp_remote_retrieve_body( $res ); if ( empty( $body ) ) { return array(); } return $this->verify( json_decode( $body, true ) ); } /** * Verify notification data before it is saved. * * @since 2.6/5.9 * * @param array $notifications Array of notifications items to verify. * * @return array */ public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh $data = array(); if ( ! is_array( $notifications ) || empty( $notifications ) ) { return $data; } $option = $this->get_option(); foreach ( $notifications as $notification ) { // Ignore if not a targeted plugin if ( ! empty( $notification['plugin'] ) && is_array( $notification['plugin'] ) && ! in_array( self::PLUGIN, $notification['plugin'], true ) ) { continue; } // Ignore if max wp version detected if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>' ) ) { continue; } // Ignore if max version has been reached if ( ! empty( $notification['maxver'] ) && version_compare( $notification['maxver'], SBIVER ) < 0 ) { continue; } // Ignore if min version has not been reached if ( ! empty( $notification['minver'] ) && version_compare( $notification['minver'], SBIVER ) > 0 ) { continue; } // Ignore if a specific sbi_status is empty or false if ( ! empty( $notification['statuscheck'] ) ) { $status_key = sanitize_key( $notification['statuscheck'] ); $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( empty( $sbi_statuses_option[ $status_key ] ) ) { continue; } } // The message and license should never be empty, if they are, ignore. if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) { continue; } // Ignore if license type does not match. $license = sbi_is_pro_version() ? 'pro' : 'free'; if ( ! in_array( $license, $notification['type'], true ) ) { continue; } // Ignore if expired. if ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) { continue; } // Ignore if notification has already been dismissed. if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict continue; } // TODO: Ignore if notification existed before installing SBI. // Prevents bombarding the user with notifications after activation. $activated = false; if ( ! empty( $activated ) && ! empty( $notification['start'] ) && $activated > strtotime( $notification['start'] ) ) { continue; } $data[] = $notification; } return $data; } /** * Verify saved notification data for active notifications. * * @since 2.6/5.9 * * @param array $notifications Array of notifications items to verify. * * @return array */ public function verify_active( $notifications ) { if ( ! is_array( $notifications ) || empty( $notifications ) ) { return array(); } // Remove notfications that are not active. foreach ( $notifications as $key => $notification ) { if ( ( ! empty( $notification['start'] ) && sbi_get_current_time() < strtotime( $notification['start'] ) ) || ( ! empty( $notification['end'] ) && sbi_get_current_time() > strtotime( $notification['end'] ) ) ) { unset( $notifications[ $key ] ); } if ( empty( $notification['recent_install_override'] ) && $this->recently_installed() ) { unset( $notifications[ $key ] ); } // Ignore if max version has been reached if ( ! empty( $notification['maxver'] ) && version_compare( $notification['maxver'], SBIVER ) < 0 ) { unset( $notifications[ $key ] ); } // Ignore if max wp version detected if ( ! empty( $notification['maxwpver'] ) && version_compare( get_bloginfo( 'version' ), $notification['maxwpver'], '>' ) ) { unset( $notifications[ $key ] ); } // Ignore if min version has not been reached if ( ! empty( $notification['minver'] ) && version_compare( $notification['minver'], SBIVER ) > 0 ) { unset( $notifications[ $key ] ); } // Ignore if a specific sbi_status is empty or false if ( ! empty( $notification['statuscheck'] ) ) { $status_key = sanitize_key( $notification['statuscheck'] ); $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( empty( $sbi_statuses_option[ $status_key ] ) ) { unset( $notifications[ $key ] ); } } } return $notifications; } /** * @return bool * * @since 1.4.5/1.4.2 */ public function recently_installed() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( ! isset( $sbi_statuses_option['first_install'] ) ) { return false; } // Plugin was installed less than a week ago if ( (int) $sbi_statuses_option['first_install'] > time() - WEEK_IN_SECONDS ) { return true; } return false; } /** * Get notification data. * * @since 2.6/5.9 * * @return array */ public function get() { if ( ! $this->has_access() ) { return array(); } $option = $this->get_option(); // Update notifications using async task. if ( empty( $option['update'] ) || sbi_get_current_time() > $option['update'] + DAY_IN_SECONDS ) { $this->update(); } $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array(); $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array(); // If there is a new user notification, add it to the beginning of the notification list $sbi_newuser = new SBI_New_User(); $newuser_notifications = $sbi_newuser->get(); if ( ! empty( $newuser_notifications ) ) { $events = array_merge( $newuser_notifications, $events ); } return array_merge( $events, $feed ); } /** * Get notification count. * * @since 2.6/5.9 * * @return int */ public function get_count() { return count( $this->get() ); } /** * Add a manual notification event. * * @since 2.6/5.9 * * @param array $notification Notification data. */ public function add( $notification ) { if ( empty( $notification['id'] ) ) { return; } $option = $this->get_option(); if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict return; } foreach ( $option['events'] as $item ) { if ( $item['id'] === $notification['id'] ) { return; } } $notification = $this->verify( array( $notification ) ); update_option( 'sbi_notifications', array( 'update' => $option['update'], 'feed' => $option['feed'], 'events' => array_merge( $notification, $option['events'] ), 'dismissed' => $option['dismissed'], ) ); } /** * Update notification data from feed. * * @since 2.6/5.9 */ public function update() { $feed = $this->fetch_feed(); $option = $this->get_option(); update_option( 'sbi_notifications', array( 'update' => sbi_get_current_time(), 'feed' => $feed, 'events' => $option['events'], 'dismissed' => $option['dismissed'], ) ); } /** * Admin area Form Overview enqueues. * * @since 2.6/5.9 */ public function enqueues() { if ( ! $this->has_access() ) { return; } $notifications = $this->get(); if ( empty( $notifications ) ) { return; } $min = ''; wp_enqueue_style( 'sbi-admin-notifications', SBI_PLUGIN_URL . "css/admin-notifications{$min}.css", array(), SBIVER ); wp_enqueue_script( 'sbi-admin-notifications', SBI_PLUGIN_URL . "js/admin-notifications{$min}.js", array( 'jquery' ), SBIVER, true ); } /** * Fields from the remote source contain placeholders to allow * some messages to be used for multiple plugins. * * @param $content string * @param $notification array * * @return string * * @since 2.6/5.9 */ public function replace_merge_fields( $content, $notification ) { $merge_fields = array( '{plugin}' => 'Instagram Feed', '{amount}' => isset( $notification['amount'] ) ? $notification['amount'] : '', '{platform}' => 'Instagram', '{lowerplatform}' => 'instagram', '{review-url}' => 'https://wordpress.org/support/plugin/instagram-feed/reviews/', '{slug}' => 'instagram-feed', '{campaign}' => 'instagram-free' ); if ( sbi_is_pro_version() ) { $merge_fields['{campaign}'] = 'instagram-pro'; $merge_fields['{plugin}'] = 'Instagram Feed Pro'; } foreach ( $merge_fields as $find => $replace ) { $content = str_replace( $find, $replace, $content ); } return $content; } /** * Output notifications on Instagram Feed admin area. * * @since 2.6/5.9 */ public function output() { $current_screen = get_current_screen(); // if we are one single feed page then return if ( isset( $_GET['feed_id'] ) ) { return; } $notifications = $this->get(); if ( empty( $notifications ) ) { return; } $notifications_html = ''; $current_class = ' current'; $content_allowed_tags = array( 'em' => array(), 'strong' => array(), 'span' => array( 'style' => array(), ), 'a' => array( 'href' => array(), 'target' => array(), 'rel' => array(), ), ); foreach ( $notifications as $notification ) { $type = $notification['id']; // Buttons HTML. $buttons_html = ''; if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) { foreach ( $notification['btns'] as $btn_type => $btn ) { if ( $type == 'review' || $type == 'discount' ) { $btn_class = $btn_type === 'primary' ? 'sbi-btn-blue' : 'sbi-btn-grey'; } else { $btn_class = $btn_type === 'primary' ? 'sbi-btn-orange' : 'sbi-btn-grey'; } if ( is_array( $btn['url'] ) ) { $args = array(); foreach ( $btn['url'] as $key => $value ) { $args[ sanitize_key( $key ) ] = sanitize_key( $value ); } $btn['url'] = wp_nonce_url( add_query_arg( $args ), 'sbi-' . $type, 'sbi_nonce' ); } if ( ! empty( $btn['attr'] ) ) { $btn['target'] = '_blank'; } if ( empty( $btn['class'] ) ) { $btn['class'] = ''; } $buttons_html .= sprintf( '%5$s', ! empty( $btn['url'] ) ? esc_url( $this->replace_merge_fields( $btn['url'], $notification ) ) : '', esc_attr( $btn['class'] ), esc_attr( $btn_class ), ! empty( $btn['target'] ) && $btn['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '', ! empty( $btn['text'] ) ? sanitize_text_field( $btn['text'] ) : '' ); } $buttons_html = ! empty( $buttons_html ) ? '
' . $buttons_html . '
' : ''; } if ( empty( $notification['image'] ) ) { $image_html = '
'; $image_html .= ''; $image_html .= '
'; } else { if ( $notification['image'] === 'balloon' ) { $image_html = '
'; $image_html .= ''; $image_html .= ' '; $image_html .= ' '; $image_html .= ''; } else if ( $notification['id'] === 'review' || $notification['id'] === 'discount' ) { $image_html = sprintf( '
notice', SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] ) ); } else { $image_html = '
'; $img_src = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] ); $image_html .= 'notice'; if ( isset( $notification['image_overlay'] ) ) { $image_html .= '
'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'
'; } } $image_html .= '
'; } // Check if it's review notice then show step #1 if ( $type == 'review' ) { $step1_img = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] ); $step1_img_html = sprintf('
notice
', $step1_img); $review_consent = get_option( 'sbi_review_consent' ); $sbi_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=instagram-lite'; // step #1 for the review notice if ( ! $review_consent ) { $step1_btns = sprintf( '', __( 'Yes', 'instagram-feed' ) ); $step1_btns .= sprintf( '%s', $sbi_open_feedback_url, __( 'No', 'instagram-feed' ) ); $notifications_html .= sprintf( '
' . $step1_img_html . '

%1$s

%2$s
', __( 'Are you enjoying the Instagram Feed Plugin?', 'instagram-feed' ), $step1_btns, ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0 ); } } $review_consent = get_option( 'sbi_review_consent' ); $review_step2_style = ''; if ( $type == 'review' && ! $review_consent ) { $review_step2_style = 'style="display: none;"'; } // Build the notification HTML for review notice if ( $type == 'review' ) { $notifications_html .= sprintf( '
' . $image_html . '

%1$s

%2$s

%3$s
', __( 'Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'instagram-feed' ), __( 'It really helps to support the plugin and help others to discover it too!', 'instagram-feed' ), $buttons_html, ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0, $current_class, ( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '', ( $type == 'review' ) ? 'rn_step_2' : '' ); } else if ( $type == 'discount' ) { // Build the notification HTML for discount notice $notifications_html .= sprintf( '
' . $image_html . '

%1$s

%2$s

%3$s
', __( 'Exclusive offer - 60% off!', 'instagram-feed' ), __( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free Instagram Feed.', 'instagram-feed' ), $buttons_html, ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0, $current_class, ( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '', ( $type == 'review' && ! $review_consent ) ? 'rn_step_2' : '' ); } else { // Notification HTML for other notices $notifications_html .= sprintf( '
' . $image_html . '

%1$s

%2$s

%3$s
', ! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '', ! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '', $buttons_html, ! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0, $current_class, ( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '' ); } // Only first notification is current. $current_class = ''; } $close_href = wp_nonce_url( add_query_arg( array( 'sbi_dismiss' => $type ) ), 'sbi-' . $type, 'sbi_nonce' ); $type_class = ''; if ( $type === 'review' || $type == 'discount' ) { $type_class = $type === 'review' ? 'sbi_review_notice' : 'sbi_discount_notice'; } ?>
> 1 ) : ?>
has_access() || empty( $_POST['id'] ) ) { wp_send_json_error(); } $id = sanitize_text_field( wp_unslash( $_POST['id'] ) ); if ( $id === 'review' ) { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); update_option( 'sbi_rating_notice', 'dismissed', false ); $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time(); update_option( 'sbi_statuses', $sbi_statuses_option, false ); } elseif ( $id === 'discount' ) { update_user_meta( get_current_user_id(), 'sbi_ignore_new_user_sale_notice', 'always' ); $current_month_number = (int)date('n', sbi_get_current_time() ); $not_early_in_the_year = ($current_month_number > 5); if ( $not_early_in_the_year ) { update_user_meta( get_current_user_id(), 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) ); } } $option = $this->get_option(); $type = is_numeric( $id ) ? 'feed' : 'events'; $option['dismissed'][] = $id; $option['dismissed'] = array_unique( $option['dismissed'] ); // Remove notification. if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) { foreach ( $option[ $type ] as $key => $notification ) { if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons unset( $option[ $type ][ $key ] ); break; } } } update_option( 'sbi_notifications', $option ); wp_send_json_success(); } } inc/admin/blocks/class-sbi-blocks.php000064400000006227150515074560013545 0ustar00hooks(); } /** * Integration hooks. * * @since 2.3 */ protected function hooks() { add_action( 'init', array( $this, 'register_block' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); } /** * Register Instagram Feed Gutenberg block on the backend. * * @since 2.3 */ public function register_block() { wp_register_style( 'sbi-blocks-styles', trailingslashit( SBI_PLUGIN_URL ) . 'css/sb-blocks.css', array( 'wp-edit-blocks' ), SBIVER ); $attributes = array( 'shortcodeSettings' => array( 'type' => 'string', ), 'noNewChanges' => array( 'type' => 'boolean', ) ); register_block_type( 'sbi/sbi-feed-block', array( 'attributes' => $attributes, 'render_callback' => array( $this, 'get_feed_html' ), ) ); } /** * Load Instagram Feed Gutenberg block scripts. * * @since 2.3 */ public function enqueue_block_editor_assets() { $db = sbi_get_database_settings(); sb_instagram_scripts_enqueue(); wp_enqueue_style( 'sbi-blocks-styles' ); wp_enqueue_script( 'sbi-feed-block', trailingslashit( SBI_PLUGIN_URL ) . 'js/sb-blocks.js', array( 'wp-blocks', 'wp-i18n', 'wp-element' ), SBIVER, true ); $shortcodeSettings = ''; $i18n = array( 'addSettings' => esc_html__( 'Add Settings', 'instagram-feed' ), 'shortcodeSettings' => esc_html__( 'Shortcode Settings', 'instagram-feed' ), 'example' => esc_html__( 'Example', 'instagram-feed' ), 'preview' => esc_html__( 'Apply Changes', 'instagram-feed' ), ); wp_localize_script( 'sbi-feed-block', 'sbi_block_editor', array( 'wpnonce' => wp_create_nonce( 'sb-instagram-blocks' ), 'canShowFeed' => ! empty( $db['connected_accounts'] ), 'configureLink' => admin_url( 'admin.php?page=sbi-settings' ), 'shortcodeSettings' => $shortcodeSettings, 'i18n' => $i18n, ) ); } /** * Get form HTML to display in a Instagram Feed Gutenberg block. * * @param array $attr Attributes passed by Instagram Feed Gutenberg block. * * @since 2.3 * * @return string */ public function get_feed_html( $attr ) { $return = ''; $shortcode_settings = isset( $attr['shortcodeSettings'] ) ? $attr['shortcodeSettings'] : ''; $shortcode_settings = str_replace(array( '[instagram-feed', ']' ), '', $shortcode_settings ); $return .= do_shortcode( '[instagram-feed '.$shortcode_settings.']' ); return $return; } /** * Checking if is Gutenberg REST API call. * * @since 2.3 * * @return bool True if is Gutenberg REST API call. */ public static function is_gb_editor() { return defined( 'REST_REQUEST' ) && REST_REQUEST && ! empty( $_REQUEST['context'] ) && 'edit' === $_REQUEST['context']; // phpcs:ignore } } inc/admin/SBI_Onboarding_wizard.php000064400000105373150515074560013276 0ustar00init(); } /** * Init Setup Dashboard. * * @since 6.0 */ public function init() { if ( is_admin() && self::should_init_wizard() ) { add_action( 'admin_menu', array( $this, 'register_menu' ) ); // add ajax listeners SBI_Feed_Saver_Manager::hooks(); SBI_Source::hooks(); self::hooks(); $this->ajax_hooks(); } } public function ajax_hooks() { add_action( 'wp_ajax_sbi_feed_saver_manager_process_wizard', array( $this , 'process_wizard_data' ) ); add_action( 'wp_ajax_sbi_feed_saver_manager_dismiss_wizard', array( $this , 'dismiss_wizard' ) ); } /** * Check if we need to Init the Onboarding wizard * * @since 6.0 */ public static function should_init_wizard() { $statues = get_option( self::$statues_name, array() ); if(!isset($statues['wizard_dismissed']) || $statues['wizard_dismissed'] === false ){ return true; } return false; } /** * Wizard Wrapper. * * @since 6.0 */ public function feed_builder() { include_once SBI_BUILDER_DIR . 'templates/wizard.php'; } /** * Register Menu. * * @since 6.0 */ public function register_menu() { $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); $feed_builder = add_submenu_page( 'sb-instagram-feed', __( 'Setup', 'instagram-feed' ), __( 'Setup', 'instagram-feed' ), $cap, 'sbi-setup', array( $this, 'feed_builder' ), 0 ); add_action( 'load-' . $feed_builder, array( $this, 'builder_enqueue_admin_scripts' ) ); } /** * Onboarding Wizard Content & Steps * * @return array * * @since 6.X */ public static function get_onboarding_wizard_content() { $data = [ 'heading' => __( 'Smash Balloon', 'instagram-feed' ), 'subheading' => __( 'Instagram Feed by', 'instagram-feed' ), 'logo' => SBI_BUILDER_URL . 'assets/img/instagram.png', 'balloon' => SBI_BUILDER_URL . 'assets/img/balloon.png', 'balloon1' => SBI_BUILDER_URL . 'assets/img/balloon-1.png', 'userIcon' => SBI_BUILDER_URL . 'assets/img/user.png', 'saveSettings' => [ 'featuresList', 'pluginsList' ], 'successMessages' => [ 'connectAccount' => __( 'Connect an Instagram Account!', 'instagram-feed' ), 'setupFeatures' => __( 'Setup Features!', 'instagram-feed' ), 'feedPlugins' => __( 'Feed plugins for # installed', 'instagram-feed' ) ], 'steps' => [ [ 'id' => 'welcome', 'template' => SBI_BUILDER_DIR . 'templates/onboarding/welcome.php', 'heading' => __( 'Let\'s set up your plugin!', 'instagram-feed' ), 'description' => __( 'Ready to add a dash of Instagram to your website? Setting up your first feed is quick and easy. We\'ll get you up and running in no time.', 'instagram-feed' ), 'button' => __( 'Launch the Setup Wizard', 'instagram-feed' ), 'img' => SBI_BUILDER_URL . 'assets/img/waving-hand.png', 'banner' => SBI_BUILDER_URL . 'assets/img/onboarding-banner.jpg', ], [ 'id' => 'add-source', 'template' => SBI_BUILDER_DIR . 'templates/onboarding/add-source.php', 'heading' => __( 'Connect your Instagram Account', 'instagram-feed' ), 'smallHeading' => __( 'STEP 1', 'instagram-feed' ), ], [ 'id' => 'configure-features', 'template' => SBI_BUILDER_DIR . 'templates/onboarding/configure-features.php', 'heading' => __( 'Configure features', 'instagram-feed' ), 'smallHeading' => __( 'STEP 2', 'instagram-feed' ), 'featuresList' => [ [ 'heading' => __( 'Instagram User Feed', 'instagram-feed' ), 'description' => __( 'Create and display Instagram feeds from connected accounts', 'instagram-feed' ), 'color' => 'green', 'active' => true, 'uncheck' => true, 'icon' => '' ], [ 'data' => [ 'id' => 'enable_email_report', 'type' => 'settings' ], 'heading' => __( 'Downtime Prevention', 'instagram-feed' ), 'description' => __( 'Prevent downtime in the event your feed is unable to update', 'instagram-feed' ), 'color' => 'green', 'active' => true, 'uncheck' => true, 'icon' => '' ], [ 'data' => [ 'id' => 'sb_instagram_disable_resize', 'type' => 'settings' ], 'heading' => __( 'Image Optimization', 'instagram-feed' ), 'description' => __( 'Optimize and locally store feed images to improve search rankings and page speed', 'instagram-feed' ), 'color' => 'green', 'active' => true, 'icon' => '' ] ], 'proFeaturesList' => [ [ 'heading' => __( 'Hashtag Feeds', 'instagram-feed' ), 'description' => __( 'Display Instagram posts that have a particular hashtag', 'instagram-feed' ), 'uncheck' => true, 'active' => false, 'icon' => '' ], [ 'heading' => __( 'Tagged Feeds', 'instagram-feed' ), 'description' => __( 'Show Instagram posts that you have been tagged in', 'instagram-feed' ), 'uncheck' => true, 'active' => false, 'icon' => '' ], [ 'heading' => __( 'Lightbox', 'instagram-feed' ), 'description' => __( 'View photos and videos in a popup lightbox directly on your site', 'instagram-feed' ), 'uncheck' => true, 'active' => false, 'icon' => '' ], ] ], [ 'id' => 'install-plugins', 'template' => SBI_BUILDER_DIR . 'templates/onboarding/install-plugins.php', 'heading' => __( 'You might also be interested in...', 'instagram-feed' ), 'description' => __( 'Enable your favorite features and disable the ones you don\'t need', 'instagram-feed' ), 'pluginsList' => self::get_awesomemotive_plugins() ], [ 'id' => 'success-page', 'template' => SBI_BUILDER_DIR . 'templates/onboarding/success-page.php', 'heading' => __( 'Awesome. You are all set up!', 'instagram-feed' ), 'description' => __( 'Here\'s an overview of everything that is setup', 'instagram-feed' ), 'upgradeContent' => [ 'heading' => __( 'Upgrade to unlock hashtag feeds, tagged feeds, a popup lightbox and more', 'instagram-feed' ), 'description' => __( 'To unlock these features and much more, upgrade to Pro and enter your license key below.', 'instagram-feed' ), 'button' => [ 'text' => __( 'Upgrade to Instagram Feed Pro', 'instagram-feed' ), 'link' => 'https://smashballoon.com/pricing/instagram-feed/?license_key&upgrade=true&utm_campaign=instagram-free&utm_source=setup&utm_medium=upgrade-license' ], 'upgradeCouppon' => sprintf( __( 'Upgrade today and %ssave 50%% on a Pro License!%s%s (auto-applied at checkout)', 'instagram-feed' ), '', '', '
' ), 'banner' => SBI_BUILDER_URL . 'assets/img/success-banner.jpg', 'upgradeFeaturesList' => [ [ 'heading' => __( 'Hashtag Feeds', 'instagram-feed' ), 'icon' => '' ], [ 'heading' => __( 'Tagged Feeds', 'instagram-feed' ), 'icon' => '' ], [ 'heading' => __( 'Lightbox', 'instagram-feed' ), 'icon' => '' ], [ 'heading' => __( 'And many more', 'instagram-feed' ), 'icon' => '' ] ] ] ], ] ]; $dynamic_features_list = self::get_dynamic_features_list(); if( isset($data['steps']) && sizeof($dynamic_features_list) > 0){ $key_cf_ft = array_search('configure-features', array_column($data['steps'], 'id')); if( $key_cf_ft !== false){ $new_features_lit = array_merge($data['steps'][$key_cf_ft]['featuresList'] , $dynamic_features_list) ; $data['steps'][$key_cf_ft]['featuresList'] = $new_features_lit; } } return $data; } /** * Return Dynamic Features List depending on multiple criteria * * @return array * * @since 6.X */ public static function get_dynamic_features_list() { $features_list = []; $smash_plugin_list = self::get_smash_plugins_list(); if( isset($smash_plugin_list['plugins']) && sizeof($smash_plugin_list['plugins']) > 0 ){ $description_plugins = implode(', ', $smash_plugin_list['text']); $search = ','; $description_plugins_text = strrev(preg_replace(strrev("/$search/"),strrev(' and '),strrev($description_plugins),1)); array_push($features_list, [ 'data' => [ 'id' => $description_plugins, 'type' => 'install_plugins', 'plugins' => 'smash' ], 'heading' => __( 'Social Feed Collection', 'instagram-feed' ), 'description' => __( 'Install' , 'instagram-feed') . ' ' . $description_plugins_text . ' ' . __('feed plugins for more fresh content', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => '' ] ); } //Reviews Plugin $reviews_plugin = self::get_smash_reviews_plugin(); if( $reviews_plugin !== false){ array_push($features_list, $reviews_plugin); } /* [ 'id' => '', 'heading' => __( 'Post and Schedule on Social Media', 'instagram-feed' ), 'description' => __( 'Install Click Social and get the ability to schedule Social media posts right from Wordpress', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => '' ], */ return $features_list; } /** * Return Uninstalled SmashBalloon Plugins * * @return array * * @since 6.X */ public static function get_smash_plugins_list(){ $installed_plugins = get_plugins(); // check whether the pro or free plugins are installed $is_facebook_installed = false; $facebook_plugin = 'custom-facebook-feed/custom-facebook-feed.php'; if ( isset( $installed_plugins['custom-facebook-feed-pro/custom-facebook-feed.php'] ) ) { $is_facebook_installed = true; $facebook_plugin = 'custom-facebook-feed-pro/custom-facebook-feed.php'; } else if ( isset( $installed_plugins['custom-facebook-feed/custom-facebook-feed.php'] ) ) { $is_facebook_installed = true; } $is_instagram_installed = false; $instagram_plugin = 'instagram-feed/instagram-feed.php'; if ( isset( $installed_plugins['instagram-feed-pro/instagram-feed.php'] ) ) { $is_instagram_installed = true; $instagram_plugin = 'instagram-feed-pro/instagram-feed.php'; } else if ( isset( $installed_plugins['instagram-feed/instagram-feed.php'] ) ) { $is_instagram_installed = true; } $is_twitter_installed = false; $twitter_plugin = 'custom-twitter-feeds/custom-twitter-feed.php'; if ( isset( $installed_plugins['custom-twitter-feeds-pro/custom-twitter-feed.php'] ) ) { $is_twitter_installed = true; $twitter_plugin = 'custom-twitter-feeds-pro/custom-twitter-feed.php'; } else if ( isset( $installed_plugins['custom-twitter-feeds/custom-twitter-feed.php'] ) ) { $is_twitter_installed = true; } $is_youtube_installed = false; $youtube_plugin = 'feeds-for-youtube/youtube-feed.php'; if ( isset( $installed_plugins['youtube-feed-pro/youtube-feed.php'] ) ) { $is_youtube_installed = true; $youtube_plugin = 'youtube-feed-pro/youtube-feed.php'; } else if ( isset( $installed_plugins['feeds-for-youtube/youtube-feed.php'] ) ) { $is_youtube_installed = true; } $smash_list = [ 'text' => [], 'plugins' => [ [ 'type' => 'instagram', 'is_istalled' => $is_instagram_installed, 'download_link' => $instagram_plugin, 'min_php' => '5.6.0' ], [ 'type' => 'facebook', 'is_istalled' => $is_facebook_installed, 'download_link' => $facebook_plugin, 'min_php' => '5.6.0' ], [ 'type' => 'twitter', 'is_istalled' => $is_twitter_installed, 'download_link' => $twitter_plugin, 'min_php' => '5.6.0' ], [ 'type' => 'youtube', 'is_istalled' => $is_youtube_installed, 'download_link' => $youtube_plugin, 'min_php' => '5.6.0' ] ] ]; foreach ($smash_list['plugins'] as $mash_plugin) { if( version_compare( PHP_VERSION , $mash_plugin['min_php'] , '<' ) ){ $mash_plugin['is_istalled'] = true; } if( $mash_plugin['type'] === self::$plugin_name || $mash_plugin['is_istalled'] === true){ unset($mash_plugin); }else{ array_push($smash_list['text'], ucfirst($mash_plugin['type'])); } } return $smash_list; } /** * Return Reviews Plugin if not Installed * * @return array * * @since 6.X */ public static function get_smash_reviews_plugin(){ $installed_plugins = get_plugins(); $min_php = '7.1'; $is_reviews_installed = false; $reviews_plugin = 'reviews-feed/sb-reviews.php'; if ( isset( $installed_plugins['reviews-feed-pro/sb-reviews-pro.php'] ) ) { $is_reviews_installed = true; $reviews_plugin = 'reviews-feed-pro/sb-reviews-pro.php'; } else if ( isset( $installed_plugins['reviews-feed/sb-reviews.php'] ) ) { $is_reviews_installed = true; } if( version_compare( PHP_VERSION , $min_php , '<' ) ){ $is_reviews_installed = true; } if( $is_reviews_installed === false ){ return [ 'data' => [ 'id' => 'reviews', 'type' => 'install_plugins' ], 'heading' => __( 'Customer Reviews Plugin', 'instagram-feed' ), 'description' => __( 'Install Reviews Feed to display customer reviews from Google or Yelp and build trust', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => '' ]; } return false; } /** * Return Awesome Motive Plugins * * @return array * * @since 6.X */ public static function get_awesomemotive_plugins(){ $installed_plugins = get_plugins(); $awesomemotive_plugins_list = [ [ 'plugin' => 'allinoneseo', 'data' => [ 'type' => 'install_plugins', 'id' => 'allinoneseo', 'pluginName' => __('All in One SEO', 'instagram-feed' ), ], 'heading' => __( 'All in One SEO Toolkit', 'instagram-feed' ), 'description' => __( 'Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs, business sites, or ecommerce sites, and much more.', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/allinoneseo.png' ], [ 'plugin' => 'monsterinsight', 'data' => [ 'type' => 'install_plugins', 'id' => 'monsterinsight', 'pluginName' => __('Monster Insights', 'instagram-feed' ), ], 'heading' => __( 'Analytics by MonsterInsights', 'instagram-feed' ), 'description' => __( 'Make it “effortless” to connect your WordPress site with Google Analytics, so you can start making data-driven decisions to grow your business.', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/monsterinsight.png', ], [ 'plugin' => 'wpforms', 'data' => [ 'type' => 'install_plugins', 'id' => 'wpforms', 'pluginName' => __('WPForms', 'instagram-feed' ), ], 'heading' => __( 'Forms by WPForms', 'instagram-feed' ), 'description' => __( 'Create contact, subscription or payment forms with the most beginner friendly drag & drop WordPress forms plugin', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/wpforms.png' ], [ 'plugin' => 'seedprod', 'data' => [ 'type' => 'install_plugins', 'id' => 'seedprod', 'pluginName' => __('SeedProd', 'instagram-feed' ), ], 'heading' => __( 'SeedProd Website Builder', 'instagram-feed' ), 'description' => __( 'A simple and powerful theme builder, landing page builder, "coming soon" page builder, and maintenance mode notice builder', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/seedprod.png' ], [ 'plugin' => 'optinmonster', 'data' => [ 'type' => 'install_plugins', 'id' => 'optinmonster', 'pluginName' => __('OptinMonster', 'instagram-feed' ), ], 'heading' => __( 'OptinMonster Popup Builder', 'instagram-feed' ), 'description' => __( 'Make popups & opt-in forms to build your email newsletter subscribers, generate leads, and close sales', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/optinmonster.png' ], [ 'plugin' => 'pushengage', 'data' => [ 'type' => 'install_plugins', 'id' => 'pushengage', 'pluginName' => __('PushEngage', 'instagram-feed' ), ], 'heading' => __( 'PushEngage Notifications', 'instagram-feed' ), 'description' => __( 'Create and send high-converting web push notifications to your website visitors.', 'instagram-feed' ), 'color' => 'blue', 'active' => true, 'icon' => SBI_BUILDER_URL . 'assets/img/pushengage.svg' ] ]; $available_plugins = []; foreach ($awesomemotive_plugins_list as $plugin) { if( !self::check_awesome_motive_plugin( $plugin['plugin'], $installed_plugins ) ){ array_push($available_plugins, $plugin); } } return array_slice($available_plugins , 0, 3); } /** * Check if AWESOME MOTIVE Plugin * * @return boolean * * @since 6.X */ public static function check_awesome_motive_plugin( $plugin, $installed_plugins ){ switch ($plugin) { case 'allinoneseo': if ( isset( $installed_plugins['all-in-one-seo-pack/all_in_one_seo_pack.php'] ) || isset( $installed_plugins['all-in-one-seo-pack-pro/all_in_one_seo_pack.php'] ) ) { return true; } return false; case 'monsterinsight': if ( isset( $installed_plugins['google-analytics-for-wordpress/googleanalytics.php'] ) || isset( $installed_plugins['google-analytics-premium/googleanalytics-premium.php'] ) ) { return true; } return false; case 'wpforms': if ( isset( $installed_plugins['wpforms-lite/wpforms.php'] ) || isset( $installed_plugins['wpforms/wpforms.php'] ) ) { return true; } return false; case 'seedprod': if ( isset( $installed_plugins['coming-soon/coming-soon.php'] ) ) { return true; } return false; case 'optinmonster': if ( isset( $installed_plugins['optinmonster/optin-monster-wp-api.php'] ) ) { return true; } return false; case 'pushengage': if ( isset( $installed_plugins['pushengage/main.php'] ) ) { return true; } return false; } } /** * Get Plugin Download * * * @since 6.X */ public static function get_plugin_download_link( $plugin_name ){ $plugin_download = false; switch ( strtolower($plugin_name) ) { case 'facebook': $plugin_download = 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip'; break; case 'instagram': $plugin_download = 'https://downloads.wordpress.org/plugin/instagram-feed.zip'; break; case 'twitter': $plugin_download = 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip'; break; case 'youtube': $plugin_download = 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip'; break; case 'reviews': $plugin_download = 'https://downloads.wordpress.org/plugin/reviews-feed.zip'; break; case 'allinoneseo': $plugin_download = 'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip'; break; case 'monsterinsight': $plugin_download = 'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip'; break; case 'wpforms': $plugin_download = 'https://downloads.wordpress.org/plugin/wpforms-lite.zip'; break; case 'seedprod': $plugin_download = 'https://downloads.wordpress.org/plugin/coming-soon.zip'; break; case 'optinmonster': $plugin_download = 'https://downloads.wordpress.org/plugin/optinmonster.zip'; break; case 'pushengage': $plugin_download = 'https://downloads.wordpress.org/plugin/pushengage.zip'; break; } return $plugin_download; } /** * Install Plugin * * * @since 6.X */ public static function install_single_plugin( $plugin_name ){ $plugin_download = self::get_plugin_download_link( strtolower( str_replace(' ', '', $plugin_name) ) ); if( $plugin_download === false || !current_user_can ('install_plugins') ){ return false; } if ( strpos( $plugin_download , 'https://downloads.wordpress.org/plugin/' ) !== 0 ) { return false; } set_current_screen( 'sbi-feed-builder' ); // Prepare variables. $url = esc_url_raw( add_query_arg( array( 'page' => 'sbi-feed-builder', ), admin_url( 'admin.php' ) ) ); $creds = request_filesystem_credentials( $url, '', false, false, null ); // Check for file system permissions. if ( false === $creds || ! WP_Filesystem( $creds ) ) { return false; } require_once SBI_PLUGIN_DIR . 'inc/admin/class-install-skin.php'; // Do not allow WordPress to search/download translations, as this will break JS output. remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); // Create the plugin upgrader with our custom skin. $installer = new \Sbi\Helpers\PluginSilentUpgrader( new \Sbi_Install_Skin() ); // Error check. if ( ! method_exists( $installer, 'install' ) || empty( $plugin_download ) ) { wp_send_json_error( $error ); } $installer->install( esc_url_raw( wp_unslash( $plugin_download ) ) ); // Flush the cache and return the newly installed plugin basename. wp_cache_flush(); $plugin_basename = $installer->plugin_info(); if ( $plugin_basename ) { activate_plugin( $plugin_basename ); } } /** * Process Wizard Data * Save Settings, Install Plugins and more * * @since 6.0.8 */ public function process_wizard_data(){ if( ! isset( $_POST['data'] ) ){ wp_send_json_error(); } check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $sbi_settings = get_option( 'sb_instagram_settings', array() ); $onboarding_data = sanitize_text_field( stripslashes( $_POST['data'] ) ); $onboarding_data = json_decode( $onboarding_data, true); foreach ($onboarding_data as $single_data) { if( $single_data['type'] === 'settings' ){ $sbi_settings[$single_data['id']] = $single_data['id'] === 'sb_instagram_disable_resize' ? false : true; } if( $single_data['type'] === 'install_plugins' && current_user_can( 'install_plugins' ) ){ $plugins = explode(',' , $single_data['id']); //Deleting Redirect Data for 3rd plugins //$this->disable_installed_plugins_redirect(); foreach ($plugins as $plugin_name) { @SBI_Onboarding_wizard::install_single_plugin( $plugin_name ); $this->disable_installed_plugins_redirect(); } } } update_option( 'sb_instagram_settings', $sbi_settings ); wp_die(); } /** * Dismiss Onboarding Wizard * * @since 6.0.8 */ public function dismiss_wizard(){ check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $sbi_statuses_option['wizard_dismissed'] = true; update_option( 'sbi_statuses', $sbi_statuses_option ); wp_send_json_error(); } /** * Disable Installed Plugins Redirect * * @since 6.0.8 */ public function disable_installed_plugins_redirect(){ //Monster Insight delete_transient( '_monsterinsights_activation_redirect' ); //All in one SEO update_option( 'aioseo_activation_redirect', true ); //WPForms update_option( 'wpforms_activation_redirect', true ); //Optin Monster delete_transient( 'optin_monster_api_activation_redirect' ); update_option( 'optin_monster_api_activation_redirect_disabled', true ); //Seed PROD update_option( 'seedprod_dismiss_setup_wizard', true ); //PushEngage delete_transient( 'pushengage_activation_redirect' ); } }inc/admin/addon-functions.php000064400000015113150515074560012222 0ustar00 'sbi-about-us', ), admin_url( 'admin.php' ) ) ); $creds = request_filesystem_credentials( $url, '', false, false, null ); // Check for file system permissions. if ( false === $creds ) { wp_send_json_error( $error ); } if ( ! WP_Filesystem( $creds ) ) { wp_send_json_error( $error ); } /* * We do not need any extra credentials if we have gotten this far, so let's install the plugin. */ require_once SBI_PLUGIN_DIR . 'inc/admin/class-install-skin.php'; // Do not allow WordPress to search/download translations, as this will break JS output. remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); // Create the plugin upgrader with our custom skin. $installer = new Sbi\Helpers\PluginSilentUpgrader( new Sbi_Install_Skin() ); // Error check. if ( ! method_exists( $installer, 'install' ) || empty( $_POST['plugin'] ) ) { wp_send_json_error( $error ); } $installer->install( esc_url_raw( wp_unslash( $_POST['plugin'] ) ) ); // Flush the cache and return the newly installed plugin basename. wp_cache_flush(); $plugin_basename = $installer->plugin_info(); if ( $plugin_basename ) { $type = 'addon'; if ( ! empty( $_POST['type'] ) ) { $type = sanitize_key( $_POST['type'] ); } // Activate the plugin silently. $activated = activate_plugin( $plugin_basename ); if ( ! is_wp_error( $activated ) ) { wp_send_json_success( array( 'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed & activated.', 'instagram-feed' ) : esc_html__( 'Addon installed & activated.', 'instagram-feed' ), 'is_activated' => true, 'basename' => $plugin_basename, ) ); } else { wp_send_json_success( array( 'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed.', 'instagram-feed' ) : esc_html__( 'Addon installed.', 'instagram-feed' ), 'is_activated' => false, 'basename' => $plugin_basename, ) ); } } wp_send_json_error( $error ); } add_action( 'wp_ajax_sbi_install_addon', 'sbi_install_addon' ); /** * Smash Balloon Encrypt or decrypt * * @param string @action * @param string @string * * @return string $output */ function sbi_encrypt_decrypt( $action, $string ) { $output = false; $encrypt_method = "AES-256-CBC"; $secret_key = 'SMA$H.BA[[OON#23121'; $secret_iv = '1231394873342102221'; // hash $key = hash( 'sha256', $secret_key ); // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning $iv = substr( hash( 'sha256', $secret_iv ), 0, 16 ); if ( $action === 'encrypt' ) { $output = openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ); $output = base64_encode( $output ); } else if ( $action === 'decrypt' ) { $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv ); } return $output; } /** * AJAX dismiss Uncanny Automator notice */ function sbi_dismiss_automator_notice() { // Run a security check. check_ajax_referer( 'sbi-admin', 'nonce' ); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $user_id = get_current_user_id(); // update the source for the automator plugin update_user_meta( $user_id, 'sbi_dismiss_automator_notice', strtotime( 'now' ) ); wp_send_json_success(); } add_action( 'wp_ajax_sbi_dismiss_automator_notice', 'sbi_dismiss_automator_notice'); /** * AJAX setup for the automator plugin to store the source information of Uncanny Automator */ function sbi_automator_setup_source() { // Run a security check. check_ajax_referer( 'sbi-admin', 'nonce' ); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } // update the source for the automator plugin update_option( 'uncannyautomator_source', 'sb' ); wp_send_json_success(); } add_action( 'wp_ajax_sbi_automator_setup_source', 'sbi_automator_setup_source');inc/admin/class-install-skin.php000064400000001116150515074560012640 0ustar00 '', // Please always pass this. 'destination' => '', // And this 'clear_destination' => false, 'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please 'clear_working' => true, 'is_multi' => false, 'hook_extra' => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters. ); $options = wp_parse_args( $options, $defaults ); /** * Filters the package options before running an update. * * See also {@see 'upgrader_process_complete'}. * * @since 4.3.0 * * @param array $options { * Options used by the upgrader. * * @type string $package Package for update. * @type string $destination Update location. * @type bool $clear_destination Clear the destination resource. * @type bool $clear_working Clear the working resource. * @type bool $abort_if_destination_exists Abort if the Destination directory exists. * @type bool $is_multi Whether the upgrader is running multiple times. * @type array $hook_extra { * Extra hook arguments. * * @type string $action Type of action. Default 'update'. * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. * @type bool $bulk Whether the update process is a bulk update. Default true. * @type string $plugin Path to the plugin file relative to the plugins directory. * @type string $theme The stylesheet or template name of the theme. * @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme', * or 'core'. * @type object $language_update The language pack update offer. * } * } */ $options = apply_filters( 'upgrader_package_options', $options ); if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times $this->skin->header(); } // Connect to the Filesystem first. $res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) ); // Mainly for non-connected filesystem. if ( ! $res ) { if ( ! $options['is_multi'] ) { $this->skin->footer(); } return false; } $this->skin->before(); if ( is_wp_error( $res ) ) { $this->skin->error( $res ); $this->skin->after(); if ( ! $options['is_multi'] ) { $this->skin->footer(); } return $res; } /* * Download the package (Note, This just returns the filename * of the file if the package is a local file) */ $download = $this->download_package( $options['package'], true ); // Allow for signature soft-fail. // WARNING: This may be removed in the future. if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) { // Don't output the 'no signature could be found' failure message for now. if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) { // Outout the failure error as a normal feedback, and not as an error: //$this->skin->feedback( $download->get_error_message() ); // Report this failure back to WordPress.org for debugging purposes. wp_version_check( array( 'signature_failure_code' => $download->get_error_code(), 'signature_failure_data' => $download->get_error_data(), ) ); } // Pretend this error didn't happen. $download = $download->get_error_data( 'softfail-filename' ); } if ( is_wp_error( $download ) ) { $this->skin->error( $download ); $this->skin->after(); if ( ! $options['is_multi'] ) { $this->skin->footer(); } return $download; } $delete_package = ( $download != $options['package'] ); // Do not delete a "local" file // Unzips the file into a temporary directory. $working_dir = $this->unpack_package( $download, $delete_package ); if ( is_wp_error( $working_dir ) ) { $this->skin->error( $working_dir ); $this->skin->after(); if ( ! $options['is_multi'] ) { $this->skin->footer(); } return $working_dir; } // With the given options, this installs it to the destination directory. $result = $this->install_package( array( 'source' => $working_dir, 'destination' => $options['destination'], 'clear_destination' => $options['clear_destination'], 'abort_if_destination_exists' => $options['abort_if_destination_exists'], 'clear_working' => $options['clear_working'], 'hook_extra' => $options['hook_extra'], ) ); $this->skin->set_result( $result ); if ( is_wp_error( $result ) ) { $this->skin->error( $result ); //$this->skin->feedback( 'process_failed' ); } else { // Installation succeeded. //$this->skin->feedback( 'process_success' ); } $this->skin->after(); if ( ! $options['is_multi'] ) { /** * Fires when the upgrader process is complete. * * See also {@see 'upgrader_package_options'}. * * @since 3.6.0 * @since 3.7.0 Added to WP_Upgrader::run(). * @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`. * * @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a * Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance. * @param array $hook_extra { * Array of bulk item update data. * * @type string $action Type of action. Default 'update'. * @type string $type Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'. * @type bool $bulk Whether the update process is a bulk update. Default true. * @type array $plugins Array of the basename paths of the plugins' main files. * @type array $themes The theme slugs. * @type array $translations { * Array of translations update data. * * @type string $language The locale the translation is for. * @type string $type Type of translation. Accepts 'plugin', 'theme', or 'core'. * @type string $slug Text domain the translation is for. The slug of a theme/plugin or * 'default' for core translations. * @type string $version The version of a theme, plugin, or core. * } * } */ do_action( 'upgrader_process_complete', $this, $options['hook_extra'] ); $this->skin->footer(); } return $result; } /** * Toggle maintenance mode for the site. * * Create/delete the maintenance file to enable/disable maintenance mode. * * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem Subclass * * @param bool $enable True to enable maintenance mode, false to disable. */ public function maintenance_mode( $enable = false ) { global $wp_filesystem; $file = $wp_filesystem->abspath() . '.maintenance'; if ( $enable ) { //$this->skin->feedback( 'maintenance_start' ); // Create maintenance file to signal that we are upgrading $maintenance_string = ''; $wp_filesystem->delete( $file ); $wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE ); } elseif ( ! $enable && $wp_filesystem->exists( $file ) ) { //$this->skin->feedback( 'maintenance_end' ); $wp_filesystem->delete( $file ); } } /** * Download a package. * * @since 2.8.0 * * @param string $package The URI of the package. If this is the full path to an * existing local file, it will be returned untouched. * @param bool $check_signatures Whether to validate file signatures. Default false. * @return string|WP_Error The full path to the downloaded package file, or a WP_Error object. */ public function download_package( $package, $check_signatures = false, $hook_extra = array() ) { /** * Filters whether to return the package. * * @since 3.7.0 * * @param bool $reply Whether to bail without returning the package. * Default false. * @param string $package The package file name. * @param WP_Upgrader $this The WP_Upgrader instance. */ $reply = apply_filters( 'upgrader_pre_download', false, $package, $this ); if ( false !== $reply ) { return $reply; } if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { //Local file or remote? return $package; //must be a local file.. } if ( empty( $package ) ) { return new WP_Error( 'no_package', $this->strings['no_package'] ); } //$this->skin->feedback( 'downloading_package', $package ); $download_file = download_url( $package, 300, $check_signatures ); if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) { return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() ); } return $download_file; } /** * Unpack a compressed package file. * * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param string $package Full path to the package file. * @param bool $delete_package Optional. Whether to delete the package file after attempting * to unpack it. Default true. * @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure. */ public function unpack_package( $package, $delete_package = true ) { global $wp_filesystem; //$this->skin->feedback( 'unpack_package' ); $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/'; //Clean up contents of upgrade directory beforehand. $upgrade_files = $wp_filesystem->dirlist( $upgrade_folder ); if ( ! empty( $upgrade_files ) ) { foreach ( $upgrade_files as $file ) { $wp_filesystem->delete( $upgrade_folder . $file['name'], true ); } } // We need a working directory - Strip off any .tmp or .zip suffixes $working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' ); // Clean up working directory if ( $wp_filesystem->is_dir( $working_dir ) ) { $wp_filesystem->delete( $working_dir, true ); } // Unzip package to working directory $result = unzip_file( $package, $working_dir ); // Once extracted, delete the package if required. if ( $delete_package ) { unlink( $package ); } if ( is_wp_error( $result ) ) { $wp_filesystem->delete( $working_dir, true ); if ( 'incompatible_archive' == $result->get_error_code() ) { return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() ); } return $result; } return $working_dir; } /** * Install a package. * * Copies the contents of a package form a source directory, and installs them in * a destination directory. Optionally removes the source. It can also optionally * clear out the destination folder if it already exists. * * @since 2.8.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * @global array $wp_theme_directories * * @param array|string $args { * Optional. Array or string of arguments for installing a package. Default empty array. * * @type string $source Required path to the package source. Default empty. * @type string $destination Required path to a folder to install the package in. * Default empty. * @type bool $clear_destination Whether to delete any files already in the destination * folder. Default false. * @type bool $clear_working Whether to delete the files form the working directory * after copying to the destination. Default false. * @type bool $abort_if_destination_exists Whether to abort the installation if * the destination folder already exists. Default true. * @type array $hook_extra Extra arguments to pass to the filter hooks called by * WP_Upgrader::install_package(). Default empty array. * } * * @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure. */ public function install_package( $args = array() ) { global $wp_filesystem, $wp_theme_directories; $defaults = array( 'source' => '', // Please always pass this 'destination' => '', // and this 'clear_destination' => false, 'clear_working' => false, 'abort_if_destination_exists' => true, 'hook_extra' => array(), ); $args = wp_parse_args( $args, $defaults ); // These were previously extract()'d. $source = $args['source']; $destination = $args['destination']; $clear_destination = $args['clear_destination']; set_time_limit( 300 ); if ( empty( $source ) || empty( $destination ) ) { return new WP_Error( 'bad_request', $this->strings['bad_request'] ); } //$this->skin->feedback( 'installing_package' ); /** * Filters the install response before the installation has started. * * Returning a truthy value, or one that could be evaluated as a WP_Error * will effectively short-circuit the installation, returning that value * instead. * * @since 2.8.0 * * @param bool|WP_Error $response Response. * @param array $hook_extra Extra arguments passed to hooked filters. */ $res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] ); if ( is_wp_error( $res ) ) { return $res; } //Retain the Original source and destinations $remote_source = $args['source']; $local_destination = $destination; $source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) ); $remote_destination = $wp_filesystem->find_folder( $local_destination ); //Locate which directory to copy to the new folder, This is based on the actual folder holding the files. if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents. $source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] ); } elseif ( count( $source_files ) == 0 ) { return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files? } else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename. $source = trailingslashit( $args['source'] ); } /** * Filters the source file location for the upgrade package. * * @since 2.8.0 * @since 4.4.0 The $hook_extra parameter became available. * * @param string $source File source location. * @param string $remote_source Remote file source location. * @param WP_Upgrader $this WP_Upgrader instance. * @param array $hook_extra Extra arguments passed to hooked filters. */ $source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] ); if ( is_wp_error( $source ) ) { return $source; } // Has the source location changed? If so, we need a new source_files list. if ( $source !== $remote_source ) { $source_files = array_keys( $wp_filesystem->dirlist( $source ) ); } /* * Protection against deleting files in any important base directories. * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending * to copy the directory into the directory, whilst they pass the source * as the actual files to copy. */ $protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' ); if ( is_array( $wp_theme_directories ) ) { $protected_directories = array_merge( $protected_directories, $wp_theme_directories ); } if ( in_array( $destination, $protected_directories ) ) { $remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) ); $destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) ); } if ( $clear_destination ) { // We're going to clear the destination if there's something there. //$this->skin->feedback( 'remove_old' ); $removed = $this->clear_destination( $remote_destination ); /** * Filters whether the upgrader cleared the destination. * * @since 2.8.0 * * @param mixed $removed Whether the destination was cleared. true on success, WP_Error on failure * @param string $local_destination The local package destination. * @param string $remote_destination The remote package destination. * @param array $hook_extra Extra arguments passed to hooked filters. */ $removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] ); if ( is_wp_error( $removed ) ) { return $removed; } } elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) { //If we're not clearing the destination folder and something exists there already, Bail. //But first check to see if there are actually any files in the folder. $_files = $wp_filesystem->dirlist( $remote_destination ); if ( ! empty( $_files ) ) { $wp_filesystem->delete( $remote_source, true ); //Clear out the source files. return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination ); } } //Create destination if needed if ( ! $wp_filesystem->exists( $remote_destination ) ) { if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) { return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination ); } } // Copy new version of item into place. $result = copy_dir( $source, $remote_destination ); if ( is_wp_error( $result ) ) { if ( $args['clear_working'] ) { $wp_filesystem->delete( $remote_source, true ); } return $result; } //Clear the Working folder? if ( $args['clear_working'] ) { $wp_filesystem->delete( $remote_source, true ); } $destination_name = basename( str_replace( $local_destination, '', $destination ) ); if ( '.' == $destination_name ) { $destination_name = ''; } $this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' ); /** * Filters the installation response after the installation has finished. * * @since 2.8.0 * * @param bool $response Installation response. * @param array $hook_extra Extra arguments passed to hooked filters. * @param array $result Installation result data. */ $res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result ); if ( is_wp_error( $res ) ) { $this->result = $res; return $res; } //Bombard the calling function will all the info which we've just used. return $this->result; } } inc/admin/class-sbi-sitehealth.php000064400000003572150515074560013145 0ustar00=' ); } /** * Loads an integration. * * @since 1.5.5 */ public function load() { $this->hooks(); } /** * Integration hooks. * * @since 1.5.5 */ protected function hooks() { add_filter( 'site_status_tests', array( $this, 'add_tests' ) ); } /** * Add MonsterInsights WP Site Health tests. * * @param array $tests The current filters array. * * @return array */ public function add_tests( $tests ) { $tests['direct']['sbi_test_check_errors'] = array( 'label' => __( 'Instagram Feed Errors', 'instagram-feed' ), 'test' => array( $this, 'test_check_errors' ) ); return $tests; } /** * Checks if there are Instagram API Errors */ public function test_check_errors() { $result = array( 'label' => __( 'Instagram Feed has no critical errors', 'instagram-feed' ), 'status' => 'good', 'badge' => array( 'label' => __( 'Instagram Feed', 'instagram-feed' ), 'color' => 'blue', ), 'description' => __( 'No critical errors have been detected.', 'instagram-feed' ), 'test' => 'sbi_test_check_errors', ); global $sb_instagram_posts_manager; if ( $sb_instagram_posts_manager->are_critical_errors() ) { $link = admin_url( 'admin.php?page=sbi-settings'); $result['status'] = 'critical'; $result['label'] = __( 'Your Instagram Feed is experiencing an error.', 'instagram-feed' ); $result['description'] = sprintf( __( 'A critical issue has been detected with your Instagram Feed. Visit the %sInstagram Feed settings page%s to fix the issue.', 'instagram-feed' ), '', '' ); } return $result; } } inc/admin/class-sbi-new-user.php000064400000041600150515074560012552 0ustar00get_option(); foreach ( $notifications as $key => $notification ) { // The message should never be empty, if they are, ignore. if ( empty( $notification['content'] ) ) { continue; } // Ignore if notification has already been dismissed. if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict continue; } $data[ $key ] = $notification; } return $data; } /** * Verify saved notification data for active notifications. * * @since 2.6 * * @param array $notifications Array of notifications items to verify. * * @return array */ public function verify_active( $notifications ) { if ( ! is_array( $notifications ) || empty( $notifications ) ) { return array(); } $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $current_time = sbi_get_current_time(); // rating notice logic $sbi_rating_notice_option = get_option( 'sbi_rating_notice', false ); $sbi_rating_notice_waiting = get_transient( 'instagram_feed_rating_notice_waiting' ); $should_show_rating_notice = ($sbi_rating_notice_waiting !== 'waiting' && $sbi_rating_notice_option !== 'dismissed'); // new user discount logic $in_new_user_month_range = true; $should_show_new_user_discount = false; $has_been_one_month_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ((int)$sbi_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1: true; if ( isset( $sbi_statuses_option['first_install'] ) && $sbi_statuses_option['first_install'] === 'from_update' ) { global $current_user; $user_id = $current_user->ID; $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' ); $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : ''; if ( $ignore_new_user_sale_notice_meta !== 'always' ) { $should_show_new_user_discount = true; } } elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $sbi_rating_notice_waiting !== 'waiting' ) { global $current_user; $user_id = $current_user->ID; $ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' ); $ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : ''; if ( $ignore_new_user_sale_notice_meta !== 'always' && isset( $sbi_statuses_option['first_install'] ) && $current_time > (int)$sbi_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS) ) { $should_show_new_user_discount = true; } } if ( sbi_is_pro_version() ) { $should_show_new_user_discount = false; } if ( isset( $notifications['review'] ) && $should_show_rating_notice ) { return array( $notifications['review'] ); } elseif ( isset( $notifications['discount'] ) && $should_show_new_user_discount ) { return array( $notifications['discount'] ); } return array(); } /** * Get notification data. * * @since 2.6 * * @return array */ public function get() { if ( ! $this->has_access() ) { return array(); } $option = $this->get_option(); // Only update if does not exist. if ( empty( $option['update'] ) ) { $this->update(); } $events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array(); $feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array(); return array_merge( $events, $feed ); } /** * Add a manual notification event. * * @since 2.6 * * @param array $notification Notification data. */ public function add( $notification ) { if ( empty( $notification['id'] ) ) { return; } $option = $this->get_option(); if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict return; } foreach ( $option['events'] as $item ) { if ( $item['id'] === $notification['id'] ) { return; } } $notification = $this->verify( array( $notification ) ); update_option( $this->option_name(), array( 'update' => $option['update'], 'feed' => $option['feed'], 'events' => array_merge( $notification, $option['events'] ), 'dismissed' => $option['dismissed'], ) ); } /** * Update notification data from feed. * * @since 2.6 */ public function update() { $feed = $this->fetch_feed(); $option = $this->get_option(); update_option( $this->option_name(), array( 'update' => time(), 'feed' => $feed, 'events' => $option['events'], 'dismissed' => $option['dismissed'], ) ); } /** * Do not enqueue anything extra. * * @since 2.6 */ public function enqueues() { } public function review_notice_consent() { //Security Checks check_ajax_referer( 'sbi_nonce', 'sbi_nonce' ); $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); if ( ! current_user_can( $cap ) ) { wp_send_json_error(); // This auto-dies. } $consent = isset( $_POST[ 'consent' ] ) ? sanitize_text_field( $_POST[ 'consent' ] ) : ''; update_option( 'sbi_review_consent', $consent ); if ( $consent == 'no' ) { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); update_option( 'sbi_rating_notice', 'dismissed', false ); $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time(); update_option( 'sbi_statuses', $sbi_statuses_option, false ); } wp_die(); } /** * Output notifications on Form Overview admin area. * * @since 2.6 */ public function output() { $notifications = $this->get(); if ( empty( $notifications ) ) { return; } // new user notices included in regular settings page notifications so this // checks to see if user is one of those pages if ( ! empty( $_GET['page'] ) && strpos( $_GET['page'], 'sbi' ) !== false ) { return; } $content_allowed_tags = array( 'em' => array(), 'strong' => array(), 'span' => array( 'style' => array(), ), 'a' => array( 'href' => array(), 'target' => array(), 'rel' => array(), ), ); $image_overlay = ''; $plugin_type = sbi_is_pro_version() ? 'pro' : 'free'; foreach ( $notifications as $notification ) { $img_src = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] ); $type = sanitize_text_field( $notification['id'] ); // check if this is a review notice if( $type == 'review' ) { $review_consent = get_option( 'sbi_review_consent' ); $sbi_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=instagram-' . $plugin_type; // step #1 for the review notice if ( ! $review_consent ) { ?>
notice

$type ) ), 'sbi-' . $type, 'sbi_nonce' ); $title = $this->get_notice_title( $notification ); $content = $this->get_notice_content( $notification, $content_allowed_tags ); $buttons = array(); if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) { foreach ( $notification['btns'] as $btn_type => $btn ) { if ( ! is_array( $btn['url'] ) ) { $buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification ); } elseif ( is_array( $btn['url'] ) ) { $buttons[ $btn_type ]['url'] = wp_nonce_url( add_query_arg( $btn['url'] ), 'sbi-' . $type, 'sbi_nonce' ); $close_href = $buttons[ $btn_type ]['url']; } $buttons[ $btn_type ]['attr'] = ''; if ( ! empty( $btn['attr'] ) ) { $buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"'; } $buttons[ $btn_type ]['class'] = ''; if ( ! empty( $btn['class'] ) ) { $buttons[ $btn_type ]['class'] = ' ' . $btn['class']; } $buttons[ $btn_type ]['text'] = ''; if ( ! empty( $btn['text'] ) ) { $buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags ); } } } } $review_consent = get_option( 'sbi_review_consent' ); $review_step2_style = ''; if ( $type == 'review' && ! $review_consent ) { $review_step2_style = 'style="display: none;"'; } ?>
>
notice

replace_merge_fields( $notification['title'], $notification ); } return $title; } /** * SBI Get Notice Content depending on the notice type * * @since 6.0 * * @param array $notification * @param array $content_allowed_tags * * @return string $content */ public function get_notice_content( $notification, $content_allowed_tags ) { $type = $notification['id']; $content = ''; // Notice content depending on notice type if ( $type == 'review' ) { $content = __( 'It really helps to support the plugin and help others to discover it too!', 'instagram-feed' ); } else if ( $type == 'discount' ) { $content = __( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free Instagram Feed.', 'instagram-feed' ); } else { if ( ! empty( $notification['content'] ) ) { $content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ); } } return $content; } /** * SBI Get Notice Title depending on the notice type * * @since 6.0 * * @param array $notification * * @return string $title */ public function dismiss() { global $current_user; $user_id = $current_user->ID; $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) { $rating_ignore = false; if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-review' ) ) { $rating_ignore = isset( $_GET['sbi_ignore_rating_notice_nag'] ) ? sanitize_text_field( $_GET['sbi_ignore_rating_notice_nag'] ) : false; } if ( 1 === (int) $rating_ignore ) { update_option( 'sbi_rating_notice', 'dismissed', false ); $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time(); update_option( 'sbi_statuses', $sbi_statuses_option, false ); } elseif ( 'later' === $rating_ignore ) { set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS ); delete_option( 'sbi_review_consent' ); update_option( 'sbi_rating_notice', 'pending', false ); } } if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) { $new_user_ignore = false; if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-discount' ) ) { $new_user_ignore = isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] ) : false; } if ( 'always' === $new_user_ignore ) { update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' ); $current_month_number = (int) date( 'n', sbi_get_current_time() ); $not_early_in_the_year = ( $current_month_number > 5 ); if ( $not_early_in_the_year ) { update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) ); } } } if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) { $bfcm_ignore = false; if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-bfcm' ) ) { $bfcm_ignore = isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] ) : false; } if ( 'always' === $bfcm_ignore ) { update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' ); } elseif ( date( 'Y', sbi_get_current_time() ) === $bfcm_ignore ) { update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) ); } update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' ); } if ( isset( $_GET['sbi_dismiss'] ) ) { $notice_dismiss = false; if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-notice-dismiss' ) ) { $notice_dismiss = sanitize_text_field( $_GET['sbi_dismiss'] ); } if ( 'review' === $notice_dismiss ) { update_option( 'sbi_rating_notice', 'dismissed', false ); $sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time(); update_option( 'sbi_statuses', $sbi_statuses_option, false ); update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' ); } elseif ( 'discount' === $notice_dismiss ) { update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' ); $current_month_number = (int) date( 'n', sbi_get_current_time() ); $not_early_in_the_year = ( $current_month_number > 5 ); if ( $not_early_in_the_year ) { update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) ); } update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' ); } } } } inc/admin/actions.php000064400000036565150515074560010605 0ustar00are_critical_errors() ) { $notice = ' !'; } $notifications = false; if ( class_exists( '\SBI_Notifications' ) ) { $sbi_notifications = new \SBI_Notifications(); $notifications = $sbi_notifications->get(); } $notice_bubble = ''; if ( empty( $notice ) && ! empty( $notifications ) && is_array( $notifications ) ) { $notice_bubble = ' ' . count( $notifications ) . ''; } add_menu_page( __( 'Instagram Feed', 'instagram-feed' ), __( 'Instagram Feed', 'instagram-feed' ). $notice_bubble . $notice, $cap, 'sb-instagram-feed', 'sb_instagram_settings_page' ); add_submenu_page( 'sb-instagram-feed', __( 'Upgrade to Pro', 'instagram-feed' ), '' . __( 'Upgrade to Pro', 'instagram-feed' ) . '', $cap, 'https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=menu-link&utm_medium=upgrade-link&utm_content=UpgradeToPro', '' ); if ( version_compare(PHP_VERSION, '7.1.0') >= 0 && !is_plugin_active( 'reviews-feed/sb-reviews.php' ) && !is_plugin_active( 'reviews-feed-pro/sb-reviews-pro.php' ) ) { add_submenu_page( 'sb-instagram-feed', __( 'Reviews Feed', 'instagram-feed' ) , '' . __( 'Reviews Feed', 'instagram-feed' ) . ''. 'New!', $cap, 'admin.php?page=sbr', '' ); } //Show a Instagram plugin menu item if it isn't already installed if( !is_plugin_active( 'custom-facebook-feed/custom-facebook-feed.php' ) && !is_plugin_active( 'custom-facebook-feed-pro/custom-facebook-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){ add_submenu_page( 'sb-instagram-feed', __( 'Facebook Feed', 'instagram-feed' ), '' . __( 'Facebook Feed', 'instagram-feed' ) . '', $cap, 'admin.php?page=cff-builder', '' ); } //Show a Twitter plugin menu item if it isn't already installed if( !is_plugin_active( 'custom-twitter-feeds/custom-twitter-feed.php' ) && !is_plugin_active( 'custom-twitter-feeds-pro/custom-twitter-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){ add_submenu_page( 'sb-instagram-feed', __( 'Twitter Feed', 'instagram-feed' ), '' . __( 'Twitter Feed', 'instagram-feed' ) . '', $cap, 'admin.php?page=sb-instagram-feed&tab=more', '' ); } //Show a YouTube plugin menu item if it isn't already installed if( !is_plugin_active( 'feeds-for-youtube/youtube-feed.php' ) && !is_plugin_active( 'youtube-feed-pro/youtube-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){ add_submenu_page( 'sb-instagram-feed', __( 'YouTube Feed', 'instagram-feed' ), '' . __( 'YouTube Feed', 'instagram-feed' ) . '', $cap, 'admin.php?page=sb-instagram-feed&tab=more', '' ); } } add_action( 'admin_menu', 'sb_instagram_menu' ); function sbi_add_settings_link( $links ) { $pro_link = '' . __( 'Upgrade to Pro', 'instagram-feed' ) . ''; $sbi_settings_link = '' . esc_html__( 'Settings', 'instagram-feed' ) . ''; array_unshift( $links, $pro_link, $sbi_settings_link ); return $links; } add_filter( "plugin_action_links_instagram-feed/instagram-feed.php", 'sbi_add_settings_link', 10, 2 ); function sb_instagram_admin_style() { wp_register_style( 'sb_instagram_admin_css', SBI_PLUGIN_URL . 'css/sb-instagram-admin.css', array(), SBIVER ); wp_enqueue_style( 'sb_instagram_admin_css' ); wp_enqueue_style( 'wp-color-picker' ); } add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_style' ); function sb_instagram_admin_scripts() { wp_enqueue_script( 'sb_instagram_admin_js', SBI_PLUGIN_URL . 'js/sb-instagram-admin-6.js', array(), SBIVER, true ); wp_localize_script( 'sb_instagram_admin_js', 'sbiA', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'sbi_nonce' => wp_create_nonce( 'sbi_nonce' ), ) ); $strings = array( 'addon_activate' => esc_html__( 'Activate', 'instagram-feed' ), 'addon_activated' => esc_html__( 'Activated', 'instagram-feed' ), 'addon_active' => esc_html__( 'Active', 'instagram-feed' ), 'addon_deactivate' => esc_html__( 'Deactivate', 'instagram-feed' ), 'addon_inactive' => esc_html__( 'Inactive', 'instagram-feed' ), 'addon_install' => esc_html__( 'Install Addon', 'instagram-feed' ), 'addon_error' => esc_html__( 'Could not install addon. Please download from wpforms.com and install manually.', 'instagram-feed' ), 'plugin_error' => esc_html__( 'Could not install a plugin. Please download from WordPress.org and install manually.', 'instagram-feed' ), 'addon_search' => esc_html__( 'Searching Addons', 'instagram-feed' ), 'ajax_url' => admin_url( 'admin-ajax.php' ), 'cancel' => esc_html__( 'Cancel', 'instagram-feed' ), 'close' => esc_html__( 'Close', 'instagram-feed' ), 'nonce' => wp_create_nonce( 'sbi-admin' ), 'almost_done' => esc_html__( 'Almost Done', 'instagram-feed' ), 'oops' => esc_html__( 'Oops!', 'instagram-feed' ), 'ok' => esc_html__( 'OK', 'instagram-feed' ), 'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'instagram-feed' ), 'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'instagram-feed' ), 'plugin_activate_btn' => esc_html__( 'Activate', 'instagram-feed' ), ); $strings = apply_filters( 'sbi_admin_strings', $strings ); wp_localize_script( 'sb_instagram_admin_js', 'sbi_admin', $strings ); wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'jquery-ui-core' ); wp_enqueue_script( 'jquery-ui-draggable' ); wp_enqueue_script( 'wp-color-picker' ); } add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_scripts' ); function sbi_formatted_error( $response ) { if ( isset( $response['error'] ) ) { $response['error']['message'] = str_replace( 'Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api', '', $response['error']['message'] ); $error = '' . sprintf( __( 'API error %s:', 'instagram-feed' ), esc_html( $response['error']['code'] ) ) . ' ' . esc_html( $response['error']['message'] ) . ''; $error .= ''; return $error; } else { $message = '' . sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] ) . ''; if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) { foreach ( $response['response']->errors as $key => $item ) { $message .= '' . esc_html( $key ) . ' - ' . esc_html( $item[0] ) . ''; } } $message .= ''; return $message; } } function sbi_connect_new_account( $access_token, $account_id ) { $split_id = explode( ' ', trim( $account_id ) ); $account_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_id[0] ); if ( ! empty( $account_id ) ) { $split_token = explode( ' ', trim( $access_token ) ); $access_token = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_token[0] ); } $account = array( 'access_token' => $access_token, 'user_id' => $account_id, 'type' => 'business', ); if ( sbi_code_check( $access_token ) ) { $account['type'] = 'basic'; } $connector = new SBI_Account_Connector(); $response = $connector->fetch( $account ); if ( isset( $response['access_token'] ) ) { $connector->add_account_data( $response ); $connector->update_stored_account(); $connector->after_update(); return $connector->get_account_data(); } else { return $response; } } add_action( 'sbi_admin_notices', 'sbi_admin_error_notices' ); function sbi_admin_error_notices() { global $sb_instagram_posts_manager; if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sbi-settings' ), true) ) { $errors = $sb_instagram_posts_manager->get_errors(); if ( ! empty( $errors ) && (! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] )) ) : ?>







get_critical_errors(); if ( $sb_instagram_posts_manager->are_critical_errors() ) : ?>

remove_all_errors(); sbi_clear_caches(); wp_send_json_success( '1' ); } add_action( 'wp_ajax_sbi_reset_log', 'sbi_reset_log' ); function sb_instagram_settings_page() { $link = admin_url( 'admin.php?page=sbi-settings' ); ?>
array( 'full' => 640, 'low' => 320, 'thumb' => 150, ), 'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150, ), ), $upload_dir = null, $upload_url = null ) { $this->post_data = $post_data; $this->image_sizes = $image_sizes; if ( ! isset( $upload_dir ) || ! isset( $upload_url ) ) { $upload = wp_upload_dir(); $upload_dir = $upload['basedir']; $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME; $upload_url = trailingslashit( $upload['baseurl'] ) . SBI_UPLOADS_NAME; } $this->upload_dir = $upload_dir; $this->upload_url = $upload_url; $this->transient_name = $transient_name; $this->fill_in_timestamp = $fill_in_timestamp; } /** * @return array * * @since 2.0/4.0 */ public function get_post_data() { if ( is_array( $this->post_data ) ) { return $this->post_data; } else { return array(); } } /** * @return array * * @since 2.0/4.0 */ public function get_resized_image_data_for_set() { return $this->resized_image_data_for_set; } /** * Loop through set of posts and update or create resized images based on * whether or not they have been created and whether or not a record has been * saved for this feed id * * @since 2.0/4.0 */ public function maybe_save_update_and_resize_images_for_posts() { global $sb_instagram_posts_manager; $posts_iterated_through = 0; $number_resized = 0; $number_updated = 0; $resized_image_data_for_set = array(); $resizing_disabled = $sb_instagram_posts_manager->image_resizing_disabled( $this->transient_name ) || $sb_instagram_posts_manager->max_resizing_per_time_period_reached(); $is_top_post_feed = ( substr( $this->transient_name, 4, 1 ) === '+' ); foreach ( $this->post_data as $single_instagram_post_data ) { if ( isset( $single_instagram_post_data['id'] ) && $posts_iterated_through < 100 ) { $single_post = new SB_Instagram_Post( $single_instagram_post_data['id'] ); $single_post->set_instagram_api_data( $single_instagram_post_data ); $resized_image_data_for_set[ $single_instagram_post_data['id'] ] = array(); if ( $is_top_post_feed ) { if ( empty( $this->first_post_top_time_stamp ) ) { $this_post_top_time_stamp = $single_post->get_top_time_stamp(); if ( empty( $this_post_top_time_stamp ) ) { $this->first_post_top_time_stamp = $this->fill_in_timestamp; } else { $this->first_post_top_time_stamp = $single_post->get_top_time_stamp(); } } } if ( ! $resizing_disabled ) { if ( ( ! $single_post->exists_in_posts_table() || ! $single_post->images_done_resizing() ) && $number_resized < 30 ) { if ( $sb_instagram_posts_manager->max_total_records_reached() ) { $sb_instagram_posts_manager->delete_least_used_image(); } if ( ! $single_post->images_done_resizing() && $single_post->exists_in_posts_table() ) { $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url ); } else { if ( $is_top_post_feed ) { if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - ( 120 * $posts_iterated_through ) - 1 ) ) ) { $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url ); } } else { if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->fill_in_timestamp ) - ( 120 * $posts_iterated_through ) ) ) ) { $single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url ); } } } $number_resized++; } else { if ( $is_top_post_feed ) { $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - ( 120 * $posts_iterated_through ) ) ); } else { $single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url ); } if ( ! $single_post->exists_in_feeds_posts_table( $this->transient_name ) ) { $single_post->insert_sbi_instagram_feeds_posts( $this->transient_name ); } $number_updated++; } $resized_image_data_for_set[ $single_instagram_post_data['id'] ] = $single_post->get_resized_image_array(); } } $posts_iterated_through++; } $this->resized_image_data_for_set = $resized_image_data_for_set; } } inc/class-sb-instagram-education.php000064400000011712150515074560013503 0ustar00hooks(); } /** * Hooks. * * @since 5.5 */ public function hooks() { $this->plugin_version = sbi_is_pro_version() ? 'pro' : 'free'; } /** * "Did You Know?" messages. * * @since 5.5 */ public function dyk_messages() { $free_messages = array( array( 'title' => esc_html__( 'Get the Most out of Hashtags', 'instagram-feed' ), 'content' => esc_html__( 'You can use hashtags on Instagram for so many things; targeted promotions, engaging with your audience, running contests, or just for categorizing posts. Learn more about how you can display Instagram hashtag feeds on your website using the Instagram Feed Pro plugin.', 'instagram-feed' ), 'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=hashtag#hashtag', 'item' => 1, ), array( 'title' => esc_html__( 'Keep Visitors on Your Site', 'instagram-feed' ), 'content' => esc_html__( "You've done the hard work of getting a visitor onto your site, now keep them there by displaying your Instagram content inside a pop-up lightbox, rather than sending your visitors away to Instagram. Learn more about the Instagram Feed Pro lightbox feature.", 'instagram-feed' ), 'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=popuplightbox#popuplightbox', 'item' => 2, ), array( 'title' => esc_html__( 'Highlight Your Posts and Create Carousels', 'instagram-feed' ), 'content' => esc_html__( "Feature specific Instagram posts in your feeds by using the Highlight layout to feature specific posts, either by using their ID or a hashtag in their caption. Also create rotating carousels of your photos and videos to best utilize the space on your site. These layouts and more are available in our Pro version.", 'instagram-feed' ), 'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=highlight#highlight', 'item' => 3, ), array( 'title' => esc_html__( 'Moderate your Feed Content', 'instagram-feed' ), 'content' => esc_html__( "Control exactly which posts show up in your feed by using the Visual Moderation Mode feature to pick and choose what to display. Remove specific posts or create a whitelist of approved content using Instagram Feed Pro.", 'instagram-feed' ), 'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=moderation#moderation', 'item' => 4, ), ); $pro_messages = array( array( 'title' => esc_html__( 'Automated YouTube Live Streaming', 'instagram-feed' ), 'content' => esc_html__( 'You can automatically feed live YouTube videos to your website using our Feeds For YouTube Pro plugin. It takes all the hassle out of publishing live videos to your site by automating the process.', 'instagram-feed' ), 'more' => 'https://smashballoon.com/youtube-feed/', 'item' => 1, ), array( 'title' => esc_html__( 'Display Facebook Pages and Groups', 'instagram-feed' ), 'content' => esc_html__( 'Have a Facebook Page or Group? Easily embed a feed of posts into your website, delivering fresh content automatically to your site from Facebook. Posts, Photos, Events, Videos, Albums, Reviews, and more!', 'instagram-feed' ), 'more' => 'https://smashballoon.com/custom-facebook-feed/', 'item' => 2, ), array( 'title' => esc_html__( 'Adding Social Proof with Twitter Feeds', 'instagram-feed' ), 'content' => esc_html__( 'Twitter testimonials are one of the best ways to add verifiable social proof to your website. They add credibility to your brand, product, or service by displaying reviews from real people to your site, helping to convert more visitors into customers. Our free Custom Twitter Feeds plugin makes displaying Tweets on your website a breeze.', 'instagram-feed' ), 'more' => 'https://wordpress.org/plugins/custom-twitter-feeds/', 'item' => 3, ), ); if ( $this->plugin_version === 'pro' ) { return $pro_messages; } return $free_messages; } /** * "Did You Know?" random message. * * @since 5.5 */ public function dyk_message_rnd() { $messages = $this->dyk_messages(); $index = array_rand( $messages ); return $messages[ $index ]; } /** * "Did You Know?" display message. * * @since 5.5 * */ public function dyk_display() { $dyk_message = $this->dyk_message_rnd(); if ( ! empty( $dyk_message['more'] ) ) { //utm_source=plugin-pro&utm_campaign= $dyk_message['more'] = add_query_arg( array( 'utm_source' => 'issueemail', 'utm_campaign' => 'instagram-'.$this->plugin_version, 'utm_medium' => $dyk_message['item'], ), $dyk_message['more'] ); } return $dyk_message; } } inc/class-sb-instagram-feed.php000064400000152460150515074560012441 0ustar00regular_feed_transient_name = $transient_name; $this->backup_feed_transient_name = SBI_BACKUP_PREFIX . $transient_name; $sbi_header_transient_name = str_replace( 'sbi_', 'sbi_header_', $transient_name ); $sbi_header_transient_name = substr($sbi_header_transient_name, 0, 44); $this->header_transient_name = $sbi_header_transient_name; $this->backup_header_transient_name = SBI_BACKUP_PREFIX . $sbi_header_transient_name; $this->post_data = array(); $this->next_pages = array(); $this->cached_feed_error = array(); $this->pages_created = 0; $this->should_paginate = true; // this is a count of how many api calls have been made for each feed // type and term. // By default the limit is 10 $this->num_api_calls = 0; $this->max_api_calls = apply_filters( 'sbi_max_concurrent_api_calls', 10 ); $this->should_use_backup = false; // used for errors and the sbi_debug report $this->report = array(); $this->resized_images = array(); $this->one_post_found = false; } public function get_feed_id() { return str_replace( '*', '', $this->regular_feed_transient_name ); } public function set_cache( $cache_seconds, $settings ) { $feed_id = $this->regular_feed_transient_name; $feed_page = 1; $this->encryption = new SB_Instagram_Data_Encryption(); $this->cache = new SB_Instagram_Cache( $feed_id, $feed_page, $cache_seconds ); $this->cache->retrieve_and_set(); } /** * @return array * * @since 2.0/5.0 */ public function get_post_data() { return $this->post_data; } /** * @return array * * @since 2.7/5.10 */ public function get_cached_feed_error() { return $this->cached_feed_error; } /** * @return array * * @since 2.0/5.0 */ public function get_next_pages() { return $this->next_pages; } /** * @return array * * @since 2.1.1/5.2.1 */ public function get_resized_images() { return $this->resized_images; } /** * @since 2.0/5.0 */ public function set_post_data( $post_data ) { $this->post_data = $post_data; } /** * @since 2.1.1/5.2.1 */ public function set_resized_images( $resized_image_data ) { $this->resized_images = $resized_image_data; } public function set_pages_created( $num ) { $this->pages_created = $num; } /** * Checks the database option related the transient expiration * to ensure it will be available when the page loads * * @return bool * * @since 2.0/4.0 */ public function regular_cache_exists() { return ! $this->cache->is_expired( 'posts' ); } /** * Checks the database option related the header transient * expiration to ensure it will be available when the page loads * * @return bool * * @since 2.0/5.0 */ public function regular_header_cache_exists() { return ! $this->cache->is_expired( 'header' ); } /** * @return bool * * @since 2.0/5.0 */ public function should_use_backup() { return $this->should_use_backup || empty( $this->post_data ); } public function should_cache_error() { global $sb_instagram_posts_manager; $error_messages = $sb_instagram_posts_manager->get_frontend_errors(); if ( ! empty( $error_messages ) ) { $this->cached_feed_error = $error_messages; return true; } return false; } /** * The header is only displayed when the setting is enabled and * an account has been connected * * Overwritten in the Pro version * * @param array $settings settings specific to this feed * @param array $feed_types_and_terms organized settings related to feed data * (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' ) * * @return bool * * @since 2.0/5.0 */ public function need_header( $settings, $feed_types_and_terms ) { $customizer = $settings['customizer']; if( $customizer ){ return true; }else{ $showheader = ($settings['showheader'] === 'on' || $settings['showheader'] === 'true' || $settings['showheader'] === true); return ($showheader && isset( $feed_types_and_terms['users'] )); } } /** * Use the transient name to retrieve cached data for header * * @since 2.0/5.0 */ public function set_header_data_from_cache() { $header_json = $this->cache->get( 'header' ); $header_cache = json_decode( $header_json, true ); if ( ! empty( $header_cache ) ) { $this->header_data = $header_cache; } } public function set_header_data( $header_data ) { $this->header_data = $header_data; } /** * @since 2.0/5.0 */ public function get_header_data() { return $this->header_data; } /** * Sets the post data, pagination data, shortcode atts used (cron cache), * and timestamp of last retrieval from transient (cron cache) * * @param array $atts available for cron caching * * @since 2.0/5.0 */ public function set_post_data_from_cache( $atts = array() ) { $posts_json = $this->cache->get( 'posts' ); $posts_data = json_decode( $posts_json, true ); if ( $posts_data ) { $post_data = isset( $posts_data['data'] ) ? $posts_data['data'] : array(); $this->post_data = $post_data; $this->next_pages = isset( $posts_data['pagination'] ) ? $posts_data['pagination'] : array(); $this->pages_created = isset( $posts_data['pages_created'] ) ? $posts_data['pages_created'] : 0; if ( isset( $posts_data['atts'] ) ) { $this->transient_atts = $posts_data['atts']; $this->last_retrieve = $posts_data['last_retrieve']; } if ( isset( $posts_data['errors'] ) ) { $this->cached_feed_error = $posts_data['errors']; } $this->add_report( 'pages created: ' . $this->pages_created .', next pages exist: ' . ! empty( $this->next_pages ) ); } } /** * Sets post data from a permanent database backup of feed * if it was created * * @since 2.0/5.0 * @since 2.0/5.1.2 if backup feed data used, header data also set from backup */ public function maybe_set_post_data_from_backup() { $backup_data = $this->cache->get( 'posts_backup' ); if ( $backup_data ) { $backup_data = json_decode( $backup_data, true ); $post_data = isset( $backup_data['data'] ) ? $backup_data['data'] : array(); $this->post_data = $post_data; $this->next_pages = isset( $backup_data['pagination'] ) ? $backup_data['pagination'] : array(); if ( isset( $backup_data['atts'] ) ) { $this->transient_atts = $backup_data['atts']; $this->last_retrieve = $backup_data['last_retrieve']; } $this->maybe_set_header_data_from_backup(); return true; } else { $this->add_report( 'no backup post data found' ); return false; } } /** * Sets header data from a permanent database backup of feed * if it was created * * @since 2.0/5.0 */ public function maybe_set_header_data_from_backup() { $backup_header_data = $this->cache->get( 'header_backup' ); if ( ! empty( $backup_header_data ) ) { $backup_header_data = json_decode( $backup_header_data, true ); $this->header_data = $backup_header_data; return true; } else { $this->add_report( 'no backup header data found' ); return false; } } /** * Returns recorded image IDs for this post set * for use with image resizing * * @return array * * @since 2.0/5.0 */ public function get_image_ids_post_set() { return $this->image_ids_post_set; } /** * Retrieves data related to resized images from custom * tables using either a number, offset, and transient name * or the ids of the posts. * * Retrieving by offset and transient name not used currently * but may be needed in future updates. * * @param array/int $num_or_array_of_ids post ids from the Instagram * API * @param int $offset number of records to skip * @param string $transient_name ID of the feed * * @return array * * @since 2.0/5.0 */ public static function get_resized_images_source_set( $num_or_array_of_ids, $offset = 0, $transient_name = '', $should_cache = true ) { global $sb_instagram_posts_manager; if ( $sb_instagram_posts_manager->image_resizing_disabled( $transient_name ) ) { return array(); } $feed_id = $transient_name; $feed_page = 1; $cache_obj = new SB_Instagram_Cache( $feed_id, $feed_page, HOUR_IN_SECONDS ); $cache_obj->retrieve_and_set(); $cache = $offset === 0 ? $cache_obj->get( 'resized_images' ) : false; if ( $cache ) { $return = json_decode( $cache, true ); } else { global $wpdb; $offset = max( 0, $offset ); $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; $feed_id_array = explode( '#', $transient_name ); $feed_id = $feed_id_array[0]; if ( is_array( $num_or_array_of_ids ) ) { $ids = $num_or_array_of_ids; $id_string = "'" . implode( "','", $ids ) . "'"; $results = $wpdb->get_results( " SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes FROM $posts_table_name AS p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id WHERE p.instagram_id IN($id_string) AND p.images_done = 1", ARRAY_A ); $return = array(); if ( !empty( $results ) && is_array( $results ) ) { foreach ( $results as $result ) { $sizes = maybe_unserialize( $result['sizes'] ); if ( ! is_array( $sizes ) ) { $sizes = array( 'full' => 640 ); } $return[ $result['instagram_id'] ] = array( 'id' => $result['media_id'], 'ratio' => $result['aspect_ratio'], 'sizes' => $sizes ); } } } else { $num = $num_or_array_of_ids; $results = $wpdb->get_results( $wpdb->prepare( " SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes FROM $posts_table_name AS p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id WHERE f.feed_id = %s AND p.images_done = 1 ORDER BY p.time_stamp DESC LIMIT %d, %d", $feed_id, $offset, (int)$num ), ARRAY_A ); $return = array(); if ( !empty( $results ) && is_array( $results ) ) { foreach ( $results as $result ) { $sizes = maybe_unserialize( $result['sizes'] ); if ( ! is_array( $sizes ) ) { $sizes = array( 'full' => 640 ); } $return[ $result['instagram_id'] ] = array( 'id' => $result['media_id'], 'ratio' => $result['aspect_ratio'], 'sizes' => $sizes ); } } } if ( $offset === 0 && $should_cache ) { $cache_obj->update_or_insert( 'resized_images', sbi_json_encode( $return ) ); } } return $return; } /** * The plugin tracks when a post was last requested so only the most * recently displayed posts are kept in the database. * This function updates the timestamp for a set of posts * on the page. * * @param $array_of_ids * * @since 2.0/5.0 */ public static function update_last_requested( $array_of_ids ) { if ( empty( $array_of_ids ) ) { return; } global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $id_string = "'" . implode( "','", $array_of_ids ) . "'"; $query = $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET last_requested = %s WHERE instagram_id IN ({$id_string});", date( 'Y-m-d H:i:s' ) ) ); } /** * Cron caching needs additional data saved in the transient * to work properly. This function checks to make sure it's present * * @return bool * * @since 2.0/5.0 */ public function need_to_start_cron_job() { return (( ! empty( $this->post_data ) && ! isset( $this->transient_atts )) || (empty( $this->post_data ) && empty( $this->cached_feed_error ))); } /** * Checks to see if there are enough posts available to create * the current page of the feed * * @param int $num * @param int $offset * * @return bool * * @since 2.0/5.0 */ public function need_posts( $num, $offset = 0, $page = 0 ) { $num_existing_posts = is_array( $this->post_data ) ? count( $this->post_data ) : 0; $num_needed_for_page = (int)$num + (int)$offset; $this->add_report( 'pages created ' .$this->pages_created . ' page on' . $page ); if ( $this->pages_created < $page ) { $this->add_report( 'need another page' ); return true; } ($num_existing_posts < $num_needed_for_page) ? $this->add_report( 'need more posts ' . $num_existing_posts . ' ' . $num_needed_for_page ) : $this->add_report( 'have enough posts' ); return ($num_existing_posts < $num_needed_for_page); } /** * Checks to see if there are additional pages available for any of the * accounts in the feed and that the max conccurrent api request limit * has not been reached * * @return bool * * @since 2.0/5.0 */ public function can_get_more_posts() { $one_type_and_term_has_more_ages = $this->next_pages !== false; $max_concurrent_api_calls_not_met = $this->num_api_calls < $this->max_api_calls; $max_concurrent_api_calls_not_met ? $this->add_report( 'max conccurrent requests not met' ) : $this->add_report( 'max concurrent met' ); $one_type_and_term_has_more_ages ? $this->add_report( 'more pages available' ) : $this->add_report( 'no next page' ); return ($one_type_and_term_has_more_ages && $max_concurrent_api_calls_not_met); } /** * Appends one filtered API request worth of posts for each feed term * * @param $settings * @param array $feed_types_and_terms organized settings related to feed data * (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' ) * @param array $connected_accounts_for_feed connected account data for the * feed types and terms * * @since 2.0/5.0 * @since 2.0/5.1 added logic to make a second attempt at an API connection * @since 2.0/5.1.2 remote posts only retrieved if API requests are not * delayed, terms shuffled if there are more than 5 * @since 2.2/5.3 added logic to refresh the access token for basic display * accounts if needed before using it in an API request */ public function add_remote_posts( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) { $this->pages_created ++; $new_post_sets = array(); $next_pages = $this->next_pages; global $sb_instagram_posts_manager; /** * Number of posts to retrieve in each API call * * @param int Minimum number of posts needed in each API request * @param array $settings Settings for this feed * * @since 2.0/5.0 */ $num = apply_filters( 'sbi_num_in_request', $settings['minnum'], $settings ); $num = max( $num, (int)$settings['apinum'] ); $params = array( 'num' => $num ); $one_successful_connection = false; $one_post_found = false; $next_page_found = false; $one_api_request_delayed = false; foreach ( $feed_types_and_terms as $type => $terms ) { if ( is_array( $terms ) && count( $terms ) > 5 ) { shuffle( $terms ); } foreach ( $terms as $term_and_params ) { if ( isset( $term_and_params['one_time_request'] ) ) { $params['num'] = 13; } $term = $term_and_params['term']; $params = array_merge( $params, $term_and_params['params'] ); if ( ! isset( $term_and_params['error'] ) && (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false) ) { $connected_account_for_term = isset( $connected_accounts_for_feed[ $term ] ) ? $connected_accounts_for_feed[ $term ] : array(); $account_type = isset( $connected_account_for_term['type'] ) ? $connected_account_for_term['type'] : 'personal'; // basic account access tokens need to be refreshed every 60 days // normally done using WP Cron but can be done here as a fail safe if ( $account_type === 'basic' ) { if ( SB_Instagram_Token_Refresher::refresh_time_has_passed_threshold( $connected_account_for_term ) && SB_Instagram_Token_Refresher::minimum_time_interval_since_last_attempt_has_passed( $connected_account_for_term ) ) { $refresher = new SB_Instagram_Token_Refresher( $connected_account_for_term ); $refresher->attempt_token_refresh(); if ( $refresher->get_last_error_code() === 10 ) { sbi_update_connected_account( $connected_accounts_for_feed[ $term ]['user_id'], array( 'private' => true ) ); $this->add_report( 'token needs refreshing ' . $term . '_' . $type ); } else { $this->add_report( 'trying to refresh token ' . $term . '_' . $type ); } } } if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) { $next_page_term = $next_pages[ $term . '_' . $type ]; if ( strpos( $next_page_term, 'https://' ) !== false ) { $connection = $this->make_api_connection( $next_page_term ); } else { $params['cursor'] = $next_page_term; $connection = $this->make_api_connection( $connected_account_for_term, $type, $params ); } } else { $connection = $this->make_api_connection( $connected_account_for_term, $type, $params ); } $this->add_report( 'api call made for ' . $term . ' - ' . $type ); $connection->connect(); $this->num_api_calls++; if ( ! $connection->has_encryption_error() && ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $one_successful_connection = true; if ( $type === 'hashtags_top' ) { SB_Instagram_Posts_Manager::maybe_update_list_of_top_hashtags( $term_and_params['hashtag_name'] ); } $sb_instagram_posts_manager->remove_error( 'connection', $connected_account_for_term ); $data = $connection->get_data(); if ( !$connected_account_for_term['is_valid'] ) { $this->add_report( 'clearing invalid token' ); $this->clear_expired_access_token_notice( $connected_account_for_term ); } if ( isset( $data[0]['id'] ) ) { $one_post_found = true; $post_set = $this->filter_posts( $data, $settings ); $post_set['term'] = $this->get_account_term( $term_and_params ); $new_post_sets[] = $post_set; } $next_page = $connection->get_next_page( $type ); if ( ! empty( $next_page ) ) { $next_pages[ $term . '_' . $type ] = $next_page; $next_page_found = true; } else { $next_pages[ $term . '_' . $type ] = false; } // One time requests are broken into smaller API requests // to avoid an API error "1" due to too much data if ( isset( $term_and_params['one_time_request'] ) && ! empty( $next_pages[ $term . '_' . $type ] ) ) { for ( $k = 1; $k <= 3; $k++ ) { if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) { $next_page_term = $next_pages[ $term . '_' . $type ]; if ( strpos( $next_page_term, 'https://' ) !== false ) { $additional_connection = $this->make_api_connection( $next_page_term ); } else { $params['cursor'] = $next_page_term; $additional_connection = $this->make_api_connection( $connected_account_for_term, $type, $params ); } $additional_connection->connect(); } if ( isset( $additional_connection ) && ! $additional_connection->is_wp_error() && ! $additional_connection->is_instagram_error() ) { $additional_data = $additional_connection->get_data(); if ( isset( $additional_data[0]['id'] ) ) { $one_post_found = true; $post_set = $this->filter_posts( $additional_data, $settings ); $post_set['term'] = $this->get_account_term( $term_and_params ); $new_post_sets[] = $post_set; $this->add_report( 'additional posts sets found in loop ' . $k ); } $next_page = $additional_connection->get_next_page( $type ); if ( ! empty( $next_page ) ) { $next_pages[ $term . '_' . $type ] = $next_page; $next_page_found = true; } else { $next_pages[ $term . '_' . $type ] = false; } } } } } else { if ( $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ] ) ) { $this->add_report( 'trying other accounts' ); $i = 0; $attempted = array( $connected_accounts_for_feed[ $term ]['access_token'] ); $success = false; $different = true; $error = false; while ( $different && ! $success && $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ], $i ) ) { $different = $this->get_different_connected_account( $type, $attempted ); $this->add_report( 'trying the account ' . $different['user_id'] ); if ( $different ) { $connected_accounts_for_feed[ $term ] = $this->get_different_connected_account( $type, $attempted ); $attempted[] = $connected_accounts_for_feed[ $term ]['user_id']; if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) { $new_connection = $this->make_api_connection( $next_pages[ $term . '_' . $type ] ); } else { $new_connection = $this->make_api_connection( $connected_accounts_for_feed[ $term ], $type, $params ); } $this->num_api_calls++; if ( ! $new_connection->is_wp_error() && ! $new_connection->is_instagram_error() ) { $one_successful_connection = true; $success = true; $sb_instagram_posts_manager->maybe_remove_display_error( 'hashtag_limit' ); $data = $new_connection->get_data(); if ( isset( $data[0]['id'] ) ) { $one_post_found = true; $post_set = $this->filter_posts( $data, $settings ); $post_set['term'] = $this->get_account_term( $term_and_params ); $new_post_sets[] = $post_set; } $next_page = $new_connection->get_next_page( $type ); if ( ! empty( $next_page ) ) { $next_pages[ $term . '_' . $type ] = $next_page; $next_page_found = true; } else { $next_pages[ $term . '_' . $type ] = false; } } else { if ( $new_connection->is_wp_error() ) { $error = $new_connection->get_wp_error(); } else { $error = $new_connection->get_data(); } } $i++; } else { $error = $connection->get_data(); } } if ( ! $success && $error ) { if ( $connection->is_wp_error() ) { SB_Instagram_API_Connect::handle_wp_remote_get_error( $error ); } else { SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ], $type ); } $next_pages[ $term . '_' . $type ] = false; } } else { if ( $connection->is_wp_error() ) { SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() ); } elseif ( $connection->has_encryption_error() ) { $error = array( 'error' => array( 'code' => '999', 'message' => __( 'Your access token could not be decrypted on this website. Reconnect this account or go to our website to learn how to prevent this.', 'instagram-feed' ) ) ); SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ], $type ); } else { SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $term ], $type ); } $next_pages[ $term . '_' . $type ] = false; } } } } } if ( ! $one_successful_connection || ($one_api_request_delayed && empty( $new_post_sets )) ) { $this->should_use_backup = true; } $posts = $this->merge_posts( $new_post_sets, $settings ); if ( ! $this->should_merge_after( $settings ) ) { if ( ! empty( $this->post_data ) && is_array( $this->post_data ) ) { $posts = array_merge( $this->post_data, $posts ); } } $posts = $this->sort_posts( $posts, $settings ); if ( $this->should_merge_after( $settings ) ) { if ( ! empty( $this->post_data ) && is_array( $this->post_data ) ) { $posts = array_merge( $this->post_data, $posts ); } } if ( $one_post_found ) { $this->one_post_found = true; } $this->post_data = $posts; if ( isset( $next_page_found ) && $next_page_found ) { $this->next_pages = $next_pages; } else { $this->next_pages = false; } } /** * Connects to the Instagram API and records returned data * * @param $settings * @param array $feed_types_and_terms organized settings related to feed data * (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' ) * @param array $connected_accounts_for_feed connected account data for the * feed types and terms * * @since 2.0/5.0 * @since 2.2/5.3 added logic to append bio data from the related * connected account if not available in the API response */ public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) { $first_user = $this->get_first_user( $feed_types_and_terms ); if ( ! empty( $settings['headersource'] ) ) { foreach ( $connected_accounts_for_feed as $connected_account ) { if ( $connected_account['username'] === $settings['headersource'] ) { $first_user = $connected_account['user_id']; } elseif ( $connected_account['user_id'] === $settings['headersource'] ) { $first_user = $connected_account['user_id']; } } } $this->header_data = false; global $sb_instagram_posts_manager; $api_requests_delayed = isset( $connected_accounts_for_feed[ $first_user ] ) ? $sb_instagram_posts_manager->are_current_api_request_delays( $connected_accounts_for_feed[ $first_user ] ) : false; if ( isset( $connected_accounts_for_feed[ $first_user ] ) && ! $api_requests_delayed ) { $connection = new SB_Instagram_API_Connect( $connected_accounts_for_feed[ $first_user ], 'header', array() ); $connection->connect(); if ( ! $connection->has_encryption_error() && ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $this->header_data = $connection->get_data(); $this->header_data['local_avatar'] = false; $sb_instagram_posts_manager->remove_error( 'connection', $connected_accounts_for_feed[ $first_user ] ); $single_source = InstagramFeed\Builder\SBI_Source::update_single_source( $connected_accounts_for_feed[ $first_user ] ); if ( ! empty( $single_source['local_avatar_url'] ) ) { $this->header_data['local_avatar'] = $single_source['local_avatar_url']; } if( isset( $this->header_data['biography'] ) && ! empty( $this->header_data['biography'] ) ) { $this->header_data['bio'] = sbi_decode_emoji( $this->header_data['biography'] ); } } else { $this->should_use_backup = true; if ( $connection->is_wp_error() ) { SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() ); } else { SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $first_user ], 'header' ); } } } } /** * Stores feed data in a transient for a specified time * * @param int $cache_time * @param bool $save_backup * @param bool $force_cache * * @since 2.0/5.0 * @since 2.0/5.1 duplicate posts removed */ public function cache_feed_data( $cache_time, $save_backup = true, $force_cache = false ) { if ( ! empty( $this->post_data ) || ! empty( $this->next_pages ) || ! empty( $this->cached_feed_error ) || $force_cache ) { $this->remove_duplicate_posts(); $this->trim_posts_to_max(); $to_cache = array( 'data' => $this->post_data, 'pagination' => $this->next_pages, 'pages_created' => $this->pages_created ); global $sb_instagram_posts_manager; $error_messages = $sb_instagram_posts_manager->get_frontend_errors(); if ( ! empty( $error_messages ) ) { $to_cache['errors'] = $error_messages; } $this->cache->update_or_insert( 'posts', sbi_json_encode( $to_cache ) ); if ( $save_backup ) { if ( isset( $to_cache['errors'] ) ) { unset( $to_cache['errors'] ); } $this->cache->update_or_insert( 'posts_backup', sbi_json_encode( $to_cache ) ); } } else { $this->add_report( 'no data not caching' ); } } /** * Stores feed data with additional data specifically for cron caching * * @param array $to_cache feed data with additional things like the shortcode * settings, when the cache was last requested, when new posts were last retrieved * @param int $cache_time how long the cache will last * @param bool $save_backup whether or not to also save this as a permanent cache * * @since 2.0/5.0 * @since 2.0/5.1 duplicate posts removed, cache set trimmed to a maximum */ public function set_cron_cache( $to_cache, $cache_time, $save_backup = true ) { if ( ! empty( $this->post_data ) || ! empty( $this->next_pages ) || ! empty( $to_cache['data'] ) || $this->should_cache_error() ) { $this->remove_duplicate_posts(); $this->trim_posts_to_max(); $to_cache['data'] = isset( $to_cache['data'] ) ? $to_cache['data'] : $this->post_data; $to_cache['pagination'] = isset( $to_cache['next_pages'] ) ? $to_cache['next_pages'] : $this->next_pages; $to_cache['atts'] = isset( $to_cache['atts'] ) ? $to_cache['atts'] : $this->transient_atts; $to_cache['last_requested'] = isset( $to_cache['last_requested'] ) ? $to_cache['last_requested'] : time(); $to_cache['last_retrieve'] = isset( $to_cache['last_retrieve'] ) ? $to_cache['last_retrieve'] : $this->last_retrieve; global $sb_instagram_posts_manager; $error_messages = $sb_instagram_posts_manager->get_frontend_errors(); if ( ! empty( $error_messages ) ) { $to_cache['errors'] = $error_messages; } else { $to_cache['errors'] = array(); } $this->cache->update_or_insert( 'posts', sbi_json_encode( $to_cache ) ); if ( $save_backup ) { if ( ! empty( $this->post_data ) || ! empty( $this->next_pages ) || ! empty( $to_cache['data'] ) ) { if ( isset( $to_cache['errors'] ) ) { unset( $to_cache['errors'] ); } $this->cache->update_or_insert( 'posts_backup', sbi_json_encode( $to_cache ) ); } } } else { $this->add_report( 'no data not caching' ); } } /** * Stores header data for a specified time as a transient * * @param int $cache_time * @param bool $save_backup * * @since 2.0/5.0 */ public function cache_header_data( $cache_time, $save_backup = true ) { if ( $this->header_data ) { $this->cache->update_or_insert( 'header', sbi_json_encode( $this->header_data ) ); if ( $save_backup ) { if ( isset( $this->header_data['errors'] ) ) { unset( $this->header_data['errors'] ); } $this->cache->update_or_insert( 'header_backup', sbi_json_encode( $this->header_data ) ); } } } /** * Used to randomly trigger an updating of the last requested data for cron caching * * @return bool * * @since 2.0/5.0 */ public function should_update_last_requested() { return (rand( 1, 20 ) === 20); } /** * Determines if pagination can and should be used based on settings and available feed data * * @param array $settings * @param int $offset * * @return bool * * @since 2.0/5.0 */ public function should_use_pagination( $settings, $offset = 0 ) { if ( $settings['minnum'] < 1 ) { return false; } $posts_available = count( $this->post_data ) - ($offset + $settings['num']); $show_loadmore_button_by_settings = ($settings['showbutton'] == 'on' || $settings['showbutton'] == 'true' || $settings['showbutton'] == true ) && $settings['showbutton'] !== 'false'; if ( $show_loadmore_button_by_settings ) { // used for permanent and whitelist feeds if ( $this->feed_is_complete( $settings, $offset ) ) { $this->add_report( 'no pagination, feed complete' ); return false; } if ( $posts_available > 0 ) { $this->add_report( 'do pagination, posts available' ); return true; } $pages = $this->next_pages; if ( $pages && ! $this->should_use_backup() ) { foreach ( $pages as $page ) { if ( ! empty( $page ) ) { return true; } } } } $this->add_report( 'no pagination, no posts available' ); return false; } /** * Generates the HTML for the feed if post data is available. Although it seems * some of the variables ar not used they are set here to hide where they * come from when used in the feed templates. * * @param array $settings * @param array $atts * @param array $feed_types_and_terms organized settings related to feed data * (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' ) * @param array $connected_accounts_for_feed connected account data for the * feed types and terms * * @return false|string * * @since 2.0/5.0 */ public function get_the_feed_html( $settings, $atts, $feed_types_and_terms, $connected_accounts_for_feed ) { global $sb_instagram_posts_manager; if ( empty( $this->post_data ) && ! empty( $connected_accounts_for_feed ) && $settings['minnum'] > 0 ) { $this->handle_no_posts_found( $settings, $feed_types_and_terms ); } $posts = array_slice( $this->post_data, 0, $settings['minnum'] ); $header_data = ! empty( $this->header_data ) ? $this->header_data : false; $first_user = ! empty( $feed_types_and_terms['users'][0] ) ? $feed_types_and_terms['users'][0]['term'] : false; $first_username = false; if ( $first_user ) { $first_username = isset( $connected_accounts_for_feed[ $first_user ]['username'] ) ? $connected_accounts_for_feed[ $first_user ]['username'] : $first_user; } elseif ( $header_data ) { // in case no connected account for feed $first_username = SB_Instagram_Parse::get_username( $header_data ); } elseif ( isset( $feed_types_and_terms['users'] ) && isset( $this->post_data[0] ) ) { // in case no connected account and no header $first_username = SB_Instagram_Parse::get_username( $this->post_data[0] ); } $use_pagination = $this->should_use_pagination( $settings, 0 ); $feed_id = $this->regular_feed_transient_name; $shortcode_atts = ! empty( $atts ) ? sbi_json_encode( $atts ) : '{}'; $settings['header_outside'] = false; $settings['header_inside'] = false; if ( $header_data && $settings['showheader'] ) { $settings['header_inside'] = true; } $other_atts = ''; $additional_classes = $this->get_feed_container_css_classes( $settings ); $other_atts .= ' data-postid="' . esc_attr( get_the_ID() ) . '"'; $other_atts .= ' data-locatornonce="' . esc_attr( wp_create_nonce( 'sbi-locator-nonce-' . get_the_ID() . '-' . $this->regular_feed_transient_name ) ) . '"'; $other_atts = $this->add_other_atts( $other_atts, $settings ); $flags = array(); if ( $sb_instagram_posts_manager->image_resizing_disabled( $feed_types_and_terms ) || $settings['isgutenberg'] ) { $flags[] = 'resizeDisable'; } elseif ( $settings['favor_local'] ) { $flags[] = 'favorLocal'; } if ( $settings['disable_js_image_loading'] ) { $flags[] = 'imageLoadDisable'; } if ( $settings['ajax_post_load'] ) { $flags[] = 'ajaxPostLoad'; } if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) ) { $flags[] = 'gdpr'; if ( ! SB_Instagram_GDPR_Integrations::blocking_cdn( $settings ) ) { $flags[] = 'overrideBlockCDN'; } } if ( ! $settings['isgutenberg'] && SB_Instagram_Feed_Locator::should_do_ajax_locating( $this->regular_feed_transient_name, get_the_ID() ) ) { $this->add_report( 'doing feed locating' ); $flags[] = 'locator'; } if ( isset( $_GET['sbi_debug'] ) || isset( $_GET['sb_debug'] ) ) { $flags[] = 'debug'; } $flags = apply_filters( 'sbi_flags', $flags, $settings ); if ( ! empty( $flags ) ) { $other_atts .= ' data-sbi-flags="' . implode(',', $flags ) . '"'; } if ( $settings['customizer'] ) { $settings['vue_args'] = [ 'condition' => ' && $parent.valueIsEnabled($parent.customizerFeedData.settings.headeroutside)' ]; } ob_start(); include sbi_get_feed_template_part( 'feed', $settings ); $html = ob_get_contents(); ob_get_clean(); if ( $settings['ajaxtheme'] ) { $html .= $this->get_ajax_page_load_html(); } return $html; } /** * Generates HTML for individual sbi_item elements * * @param array $settings * @param int $offset * @param array $feed_types_and_terms organized settings related to feed data * (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' ) * @param array $connected_accounts_for_feed connected account data for the * feed types and terms * * @return false|string * * @since 2.0/5.0 */ public function get_the_items_html( $settings, $offset, $feed_types_and_terms, $connected_accounts_for_feed ) { if ( empty( $this->post_data ) ) { ob_start(); $html = ob_get_contents(); ob_get_clean(); ?>

post_data, $offset, $settings['num'] ); ob_start(); $this->posts_loop( $posts, $settings, $offset ); $html = ob_get_contents(); ob_get_clean(); return $html; } /** * Overwritten in the Pro version * * @return object */ public function make_api_connection( $connected_account_or_page, $type = NULL, $params = NULL ) { return new SB_Instagram_API_Connect( $connected_account_or_page, $type, $params ); } /** * When the feed is loaded with AJAX, the JavaScript for the plugin * needs to be triggered again. This function is a workaround that adds * the file and settings to the page whenever the feed is generated. * * @return string * * @since 2.0/5.0 */ public static function get_ajax_page_load_html() { if ( SB_Instagram_Blocks::is_gb_editor() ) { return ''; } $sbi_options = sbi_get_database_settings(); $font_method = 'svg'; $upload = wp_upload_dir(); $resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME ); $js_options = array( 'font_method' => $font_method, 'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png', 'resized_url' => $resized_url, 'ajax_url' => admin_url( 'admin-ajax.php' ), ); $encoded_options = sbi_json_encode( $js_options ); $js_option_html = ''; $js_option_html .= ""; return $js_option_html; } /** * Overwritten in the Pro version * * @param $feed_types_and_terms * * @return string * * @since 2.1/5.2 */ public function get_first_user( $feed_types_and_terms ) { if ( isset( $feed_types_and_terms['users'][0] ) ) { return $feed_types_and_terms['users'][0]['term']; } if ( isset( $feed_types_and_terms['tagged'][0] ) ) { return $feed_types_and_terms['tagged'][0]['term']; } else { return ''; } } /** * Adds recorded strings to an array * * @param $to_add * * @since 2.0/5.0 */ public function add_report( $to_add ) { $this->report[] = $to_add; } /** * @return array * * @since 2.0/5.0 */ public function get_report() { return $this->report; } /** * Additional options/settings added to the main div * for the feed * * Overwritten in the Pro version * * @param $other_atts * @param $settings * * @return string */ protected function add_other_atts( $other_atts, $settings ) { return $other_atts; } /** * Used for filtering a single API request worth of posts * * Overwritten in the Pro version * * @param array $post_set a single set of post data from the api * * @return mixed|array * * @since 2.0/5.0 */ protected function filter_posts( $post_set, $settings = array() ) { // array_unique( $post_set, SORT_REGULAR); if ( $settings['media'] === 'all' ) { return $post_set; } $media_filter = $settings['media'] !== 'all' ? $settings['media'] : false; if ( $media_filter ) { $media_filter = is_array( $media_filter ) ? $media_filter : array( $media_filter ); } $video_types = ! empty( $settings['videotypes'] ) ? explode( ',', str_replace( ' ', '', strtolower( $settings['videotypes'] ) ) ) : array( 'igtv', 'regular', 'reels' ); $filtered_posts = array(); foreach ( $post_set as $post ) { $keep_post = false; $is_hidden = false; $passes_media_filter = true; if ( $media_filter ) { $media_type = SB_Instagram_Parse::get_media_type( $post ); if ( $media_type === 'video' && in_array( 'videos', $media_filter, true ) ) { if ( ! empty( $video_types ) ) { $video_type = SB_Instagram_Parse::get_media_product_type( $post ); $video_type = 'feed' === $video_type ? 'regular' : $video_type; if ( ! in_array( $video_type, $video_types, true ) ) { $passes_media_filter = false; } } } elseif ( $media_type === 'video' && ! in_array( 'videos', $media_filter, true ) ) { $passes_media_filter = false; } elseif ( $media_type === 'image' && ! in_array( 'photos', $media_filter, true ) ) { $passes_media_filter = false; } elseif ( $media_type === 'carousel' && ! in_array( 'photos', $media_filter, true ) ) { $passes_media_filter = false; } } if ( ! $is_hidden && $passes_media_filter ) { $keep_post = true; } $keep_post = apply_filters( 'sbi_passes_filter', $keep_post, $post, $settings ); if ( $keep_post ) { $filtered_posts[] = $post; } } return $filtered_posts; } protected function handle_no_posts_found( $settings = array(), $feed_types_and_terms = array() ) { global $sb_instagram_posts_manager; $error_message_return = array( 'error_message' => __( 'Error: No posts found.', 'instagram-feed' ), 'admin_only' => __( 'Make sure this account has posts available on instagram.com.', 'instagram-feed' ), 'frontend_directions' => '' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '', 'backend_directions' => '' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '' ); $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); } protected function remove_duplicate_posts() { $posts = $this->post_data; $ids_in_feed = array(); $non_duplicate_posts = array(); $removed = array(); foreach ( $posts as $post ) { $post_id = SB_Instagram_Parse::get_post_id( $post ); if ( ! in_array( $post_id, $ids_in_feed, true ) ) { $ids_in_feed[] = $post_id; $non_duplicate_posts[] = $post; } else { $removed[] = $post_id; } } $this->add_report( 'removed duplicates: ' . implode(', ', $removed ) ); $this->set_post_data( $non_duplicate_posts ); } /** * Used for limiting the cache size * * @since 2.0/5.1.1 */ protected function trim_posts_to_max() { if ( ! is_array( $this->post_data ) ) { return; } $max = apply_filters( 'sbi_max_cache_size', 500 ); $this->set_post_data( array_slice( $this->post_data , 0, $max ) ); } /** * Used for permanent feeds or white list feeds to * stop pagination if all posts are already added * * Overwritten in the Pro version * * @param array $settings * @param int $offset * * @return bool * * @since 2.0/5.0 */ protected function feed_is_complete( $settings, $offset = 0 ) { return false; } /** * @param $connected_account_for_term * * @since 2.0/5.1.2 */ private function clear_expired_access_token_notice( $connected_account_for_term ) { InstagramFeed\Builder\SBI_Source::clear_error( $connected_account_for_term['user_id'] ); } /** * Iterates through post data and tracks the index of the current post. * The actual post ids of the posts are stored in an array so the plugin * can search for local images that may be available. * * @param array $posts final filtered post data for the feed * @param array $settings * @param int $offset * * @since 2.0/5.0 */ private function posts_loop( $posts, $settings, $offset = 0 ) { $image_ids = array(); $post_index = $offset; $icon_type = 'svg'; $resized_images = $this->get_resized_images(); foreach ( $posts as $post ) { $image_ids[] = SB_Instagram_Parse::get_post_id( $post ); $account_type = SB_Instagram_Parse::get_account_type( $post ); include sbi_get_feed_template_part( 'item', $settings ); $post_index++; } $this->image_ids_post_set = $image_ids; } private function get_account_term( $term_and_params ) { if ( isset( $term_and_params['hashtag_name'] ) ) { return '#' . $term_and_params['hashtag_name']; } else { return ''; } } /** * Uses array of API request results and merges them based on how * the feed should be sorted. Mixed feeds are always sorted alternating * since there is no post date for hashtag feeds. * * * @param array $post_sets an array of single API request worth * of posts * @param array $settings * * @return array * * @since 2.0/5.0 */ private function merge_posts( $post_sets, $settings ) { $merged_posts = array(); if ( $settings['sortby'] === 'alternate' || $settings['sortby'] === 'api' && isset( $post_sets[1] ) ) { // don't bother merging posts if there is only one post set if ( isset( $post_sets[1] ) ) { $min_cycles = $settings['sortby'] === 'api' ? min( 200 / count( $post_sets ) + 5, 50 ) : max( 1, (int)$settings['minnum'] ); $terms = array(); for( $i = 0; $i <= $min_cycles; $i++ ) { $ii = 0; foreach ( $post_sets as $post_set ) { if ( isset( $post_sets[ $ii ]['term'] ) ) { $term = $post_sets[ $ii ]['term']; unset( $post_sets[ $ii ]['term'] ); if ( ! isset( $terms[ $ii ] ) ) { $terms[ $ii ] = $term; // } if ( strpos( $term, '#' ) !== false ) { $post_index = 0; foreach ( $post_sets[ $ii ] as $post ) { $post_sets[ $ii ][ $post_index ]['term'] = $term; $post_index++; } } } if ( isset( $post_set[ $i ] ) && isset( $post_set[ $i ]['id'] ) ) { $post_set[ $i ]['term'] = $terms[ $ii ]; $merged_posts[] = $post_set[ $i ]; } $ii++; } } } else { if ( isset( $post_sets[0]['term'] ) ) { $term = $post_sets[0]['term']; unset( $post_sets[0]['term'] ); if ( strpos( $term, '#' ) !== false ) { $post_index = 0; foreach ( $post_sets[0] as $post ) { $post_sets[0][ $post_index ]['term'] = $term; $post_index++; } } } $merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array(); } } elseif ( $settings['sortby'] === 'api' ) { if ( isset( $post_sets[0] ) ) { if ( isset( $post_sets[0]['term'] ) ) { $term = $post_sets[0]['term']; unset( $post_sets[0]['term'] ); if ( strpos( $term, '#' ) !== false ) { $post_index = 0; foreach ( $post_sets[0] as $post ) { $post_sets[0][ $post_index ]['term'] = $term; $post_index++; } } } $post_set_index = 0; foreach ( $post_sets as $post_set ) { if ( isset( $post_sets[ $post_set_index ]['term'] ) ) { $term = $post_sets[ $post_set_index ]['term']; unset( $post_sets[ $post_set_index ]['term'] ); if ( strpos( $term, '#' ) !== false ) { $post_index = 0; foreach ( $post_sets[0] as $post ) { $post_sets[ $post_set_index ][ $post_index ]['term'] = $term; $post_index++; } } } $merged_posts = array_merge( $merged_posts, $post_set ); $post_set_index ++; } } } else { // don't bother merging posts if there is only one post set if ( isset( $post_sets[1] ) ) { $terms = array(); $ii = 0; foreach ( $post_sets as $post_set ) { if ( isset( $post_set[0]['id'] ) ) { if ( isset( $post_sets[ $ii ]['term'] ) ) { if ( ! isset( $terms[ $ii ] ) ) { $terms[ $ii ] = $post_set['term']; } unset( $post_sets[ $ii ]['term'] ); $iii = 0; foreach ( $post_sets[ $ii ] as $post ) { $post_sets[ $ii ][ $iii ]['term'] = $terms[ $ii ]; $iii++; } } $merged_posts = array_merge( $merged_posts, $post_sets[ $ii ] ); $ii++; } } } else { if ( isset( $post_sets[0]['term'] ) ) { $term = $post_sets[0]['term']; unset( $post_sets[0]['term'] ); if ( strpos( $term, '#' ) !== false ) { $post_index = 0; foreach ( $post_sets[0] as $post ) { $post_sets[0][ $post_index ]['term'] = $term; $post_index++; } } } $merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array(); } } if ( isset( $merged_posts['term'] ) ) { unset( $merged_posts['term'] ); } return $merged_posts; } /** * Sorting by date will be more accurate for multi-term * feeds if posts are merged before sorting. * * @param array $settings * * @return bool * * @since 5.10.1 */ protected function should_merge_after( $settings ) { if ( ! isset( $settings['sortby'] ) ) { return false; } $merge_befores = array( 'alternate', 'api', 'random', 'likes' ); if ( ! in_array( $settings['sortby'], $merge_befores, true ) ) { return false; } return true; } /** * Sorts a post set based on sorting settings. Sorting by "alternate" * is done when merging posts for efficiency's sake so the post set is * just returned as it is. * * Overwritten in the Pro version. * * @param array $post_set * @param array $settings * * @return mixed|array * * @since 2.0/5.0 * @since 2.1/5.2 added filter hook for applying custom sorting */ protected function sort_posts( $post_set, $settings ) { if ( empty( $post_set ) ) { return $post_set; } // sorting done with "merge_posts" to be more efficient if ( $settings['sortby'] === 'alternate' || $settings['sortby'] === 'api' ) { $return_post_set = $post_set; } elseif ( $settings['sortby'] === 'random' ) { /* * randomly selects posts in a random order. Cache saves posts * in this random order so paginating does not cause some posts to show up * twice or not at all */ usort($post_set, 'sbi_rand_sort' ); $return_post_set = $post_set; } else { // compares posted on dates of posts usort($post_set, 'sbi_date_sort' ); $return_post_set = $post_set; } /** * Apply a custom sorting of posts * * @param array $return_post_set Ordered set of filtered posts * @param array $settings Settings for this feed * * @since 2.1/5.2 */ return apply_filters( 'sbi_sorted_posts', $return_post_set, $settings ); } /** * Can trigger a second attempt at getting posts from the API * * Overwritten in the Pro version * * @param string $type * @param array $connected_account_with_error * @param int $attempts * * @return bool * * @since 2.0/5.1.1 */ protected function can_try_another_request( $type, $connected_account_with_error, $attempts = 0 ) { return false; } /** * returns a second connected account if it exists * * Overwritten in the Pro version * * @param string $type * @param array $attempted_connected_accounts * * @return bool * * @since 2.0/5.1.1 */ protected function get_different_connected_account( $type, $attempted_connected_accounts ) { return false; } /** * Generates The Feed Container CSS classes * * @param array $settings * * @return string * * @since 6.0 */ function get_feed_container_css_classes( $settings ){ $customizer = $settings['customizer']; if($customizer){ }else{ $classes = array(); if ( empty( $settings['widthresp'] ) || $settings['widthresp'] == 'on' || $settings['widthresp'] == 'true' || $settings['widthresp'] === true ) { if ( $settings['widthresp'] !== 'false' ) { $classes[] = 'sbi_width_resp'; } } if ( ! empty( $settings['class'] ) ) { $classes[] = esc_attr( $settings['class'] ); } if ( ! empty( $settings['height'] ) && (((int)$settings['height'] < 100 && $settings['heightunit'] === '%') || $settings['heightunit'] === 'px') ) { $classes[] = 'sbi_fixed_height'; } if ( ! empty( $settings['disablemobile'] ) && ($settings['disablemobile'] == 'on' || $settings['disablemobile'] == 'true' || $settings['disablemobile'] == true) ) { if ( $settings['disablemobile'] !== 'false' ) { $classes[] = 'sbi_disable_mobile'; } } $additional_classes = ''; if ( ! empty( $classes ) ) { $additional_classes = ' ' . implode( ' ', $classes ); } return $additional_classes; } return ''; } } inc/class-sb-instagram-single.php000064400000015325150515074560013015 0ustar00permalink = $permalink_or_permalink_id; $exploded_permalink = explode( '/', $permalink_or_permalink_id ); $permalink_id = $exploded_permalink[4]; $this->permalink_id = $permalink_id; } else { $this->permalink_id = $permalink_or_permalink_id; $this->permalink = 'https://www.instagram.com/p/' . $this->permalink_id; } $this->error = false; $this->encryption = new SB_Instagram_Data_Encryption(); } /** * Sets post data from cache or fetches new data * if it doesn't exist or hasn't been updated recently * * @since 2.5.3/5.8.3 */ public function init() { $this->post = $this->maybe_saved_data(); if ( empty( $this->post ) || ! $this->was_recently_updated() ) { if ( ! $this->should_delay_oembed_request() ) { $data = $this->fetch(); if ( ! empty( $data ) ) { $data = $this->parse_and_restructure( $data ); $this->post = $data; $this->update_last_update_timestamp(); $this->update_single_cache(); } elseif ( $data === false ) { $this->add_oembed_request_delay(); } } } } /** * @return array * * @since 2.5.3/5.8.3 */ public function get_post() { return $this->post; } public function get_error() { return $this->error; } /** * Image URLs expire so this will compare when the data * was last updated from the API * * @return bool * * @since 2.5.3/5.8.3 */ public function was_recently_updated() { if ( ! isset( $this->post['last_update'] ) ) { return false; } return ( time() - 14 * DAY_IN_SECONDS ) < $this->post['last_update']; } /** * Makes an HTTP request for fresh data from the oembed * endpoint. Returns false if no new data or there isn't * a business access token found. * * @return bool|mixed|null * * @since 2.5.3/5.8.3 */ public function fetch() { // need a connected business account for this to work $access_token = SB_Instagram_Oembed::last_access_token(); if ( empty( $access_token ) ) { $this->error = 'No access token'; return false; } $url = SB_Instagram_Oembed::oembed_url(); $fetch_url = add_query_arg( array( 'url' => $this->permalink, 'access_token' => $access_token, ), $url ); $result = wp_remote_get( esc_url_raw( $fetch_url ) ); $data = false; if ( ! is_wp_error( $result ) ) { $data = isset( $result['body'] ) ? json_decode( $result['body'], true ) : false; if ( $data && isset( $data['error'] ) ) { $this->add_oembed_request_delay(); $this->error = sprintf( __( 'API error %s:', 'instagram-feed' ), $data['error']['code'] ) . ' ' . $data['error']['message']; $data = false; } } else { $error = ''; foreach ( $result->errors as $key => $item ) { $error .= $key . ' - ' . $item[0] . ' '; } $this->error = $error; } return $data; } /** * If there was a problem with the last oEmbed request, the plugin * waits 5 minutes to try again to prevent burning out the access token * or causing Instagram to throttle HTTP requests from the server * * @return bool * * @since 2.5.3/5.8.3 */ public function should_delay_oembed_request() { return ( get_transient( 'sbi_delay_oembeds_' . $this->permalink_id ) !== false ); } /** * If there's an error, API requests are delayed 5 minutes * for the specific permalink/post * * @since 2.5.3/5.8.3 */ public function add_oembed_request_delay() { set_transient( 'sbi_delay_oembeds_' . $this->permalink_id, true, 300 ); } /** * Track last API request due to some data expiring and * needing to be refreshed * * @since 2.5.3/5.8.3 */ private function update_last_update_timestamp() { $this->post['last_update'] = time(); } /** * Data retrieved with this method has it's own cache * * @since 2.5.3/5.8.3 */ private function update_single_cache() { $stored_option = get_option( 'sbi_single_cache', array() ); if ( ! is_array( $stored_option ) ) { $stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true ); } $new = array( $this->permalink_id => $this->post ); $stored_option = array_merge( $new, (array) $stored_option ); // only latest 400 posts $stored_option = array_slice( $stored_option, 0, 400 ); update_option( 'sbi_single_cache', $this->encryption->encrypt( sbi_json_encode( $stored_option ) ), false ); } /** * Data is restructured to look like regular API data * for ease of use with other plugin features * * @param $data array * * @return array * * @since 2.5.3/5.8.3 */ private function parse_and_restructure( $data ) { // TODO: parse all of the available data for this post, currently just thumbnail $return = array( 'thumbnail_url' => '', 'id' => $this->permalink_id, 'media_type' => 'OEMBED', ); if ( ! empty( $data['thumbnail_url'] ) ) { $return['thumbnail_url'] = $data['thumbnail_url']; } apply_filters( 'sbi_single_parse_and_restructure', $return ); return $return; } /** * Returns whatever data exists or empty array * * @return array * * @since 2.5.3/5.8.3 */ private function maybe_saved_data() { $stored_option = get_option( 'sbi_single_cache', array() ); if ( ! is_array( $stored_option ) ) { $stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true ); } $data = array(); if ( ! empty( $stored_option[ $this->permalink_id ] ) ) { return $stored_option[ $this->permalink_id ]; } else { $settings = get_option( 'sb_instagram_settings', array() ); $resize_disabled = isset( $settings['sb_instagram_disable_resize'] ) && $settings['sb_instagram_disable_resize'] === 'on'; if ( ! $resize_disabled ) { global $wpdb; $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $results = $wpdb->get_col( $wpdb->prepare( "SELECT json_data FROM $posts_table_name WHERE instagram_id = %s LIMIT 1", $this->permalink_id ) ); if ( isset( $results[0] ) ) { $data = json_decode( $this->encryption->decrypt( $results[0] ), true ); } } } return $data; } } inc/class-sb-instagram-token-refresher.php000064400000011663150515074560014640 0ustar00connected_account = $connected_account; $this->report = array(); } public function get_report() { return $this->report; } /** * The plugin will attempt to refresh the token well * before it expires. This function determines if the * minimum amount of time has passed before the token * can be refreshed * * @param $connected_account * * @return bool */ public static function refresh_time_has_passed_threshold( $connected_account ) { $expiration_timestamp = isset( $connected_account['expires_timestamp'] ) ? $connected_account['expires_timestamp'] : time(); $current_time = sbi_get_current_timestamp(); $refresh_threshold = $expiration_timestamp - SBI_REFRESH_THRESHOLD_OFFSET; if ( $refresh_threshold < $current_time ) { return true; } return false; } /** * Instagram will automatically reject API calls if * done too frequently. This method returns true if * there has been a minimum amount of time since the last * API connection was attemplted * * @param $connected_account * * @return bool */ public static function minimum_time_interval_since_last_attempt_has_passed( $connected_account ) { $last_attempt = isset( $connected_account['last_refresh_attempt'] ) ? (int) $connected_account['last_refresh_attempt'] : 0; $current_time = sbi_get_current_timestamp(); if ( $current_time > $last_attempt + SBI_MINIMUM_INTERVAL ) { return true; } return false; } /** * Returns true if the minimum time has passed since the last * successfull access token refresh and the minimum time has passed * since the last attempt. * * @return bool */ public function should_attempt_refresh() { if ( self::refresh_time_has_passed_threshold( $this->connected_account ) ) { if ( self::minimum_time_interval_since_last_attempt_has_passed( $this->connected_account ) ) { $this->report['should_do_update'] = true; $this->report['reason'] = ''; return true; } else { $this->report['should_do_update'] = false; $this->report['reason'] = 'has not been enough time since last attempt'; } } else { $this->report['should_do_update'] = false; $this->report['reason'] = 'token expiration date not close enough'; } return false; } /** * Attempts to refresh the token by connecting to the * Instagram API. Logs information about the error if unsuccessful. * * @return bool */ public function attempt_token_refresh() { $this->update_last_attempt_timestamp(); $connection = new SB_Instagram_API_Connect( $this->connected_account, 'access_token', array() ); $connection->connect(); if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $access_token_data = $connection->get_data(); if ( ! empty( $access_token_data ) && ! empty( $access_token_data['expires_in'] ) ) { $this->report['did_update'] = true; $this->add_renewal_data( $access_token_data ); return true; } else { $this->report['did_update'] = false; $this->report['reason'] = 'successful connection but no data returned'; } } else { $this->report['did_update'] = false; $this->report['reason'] = 'could not connect to Instagram'; $this->report['error_log'] = $connection; } return false; } /** * Updates data related to when the last attempt was made to refresh * the access token for a connected account and saves it in the database. */ public function update_last_attempt_timestamp() { sbi_update_connected_account( $this->connected_account['user_id'], array( 'last_updated' => time() ) ); } /** * Helps determine if an access token is from a private * account which can't be refreshed * * @return bool * * @since 2.4.7/5.7.1 */ public function get_last_error_code() { if ( isset( $this->report['error_log'] ) ) { if ( ! is_wp_error( $this->report['error_log'] ) ) { $error = $this->report['error_log']->get_data(); return $error['error']['code']; } } return false; } /** * Updates data related to the renewed access token * for a connected account and saves it in the database. * * @param $token_data */ private function add_renewal_data( $token_data ) { $expires_in = $token_data['expires_in']; $expires_timestamp = sbi_get_current_timestamp() + $expires_in; $to_update = array( 'access_token' => $token_data['access_token'], 'expires' => date( 'Y-m-d H:i:s', $expires_timestamp ), ); sbi_update_connected_account( $this->connected_account['user_id'], $to_update ); } } inc/email.php000064400000030107150515074560007126 0ustar00 <?php echo esc_html( $title ); ?>
<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>
' . esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) ) . '' ); ?> ', '' ); ?>
inc/class-sb-instagram-connected-account.php000064400000030117150515074560015124 0ustar00account = $search_term_or_account; } else { $this->account = self::lookup( $search_term_or_account, $search_type ); } } /** * @return array * * @since 5.10 */ public function get_account_data() { return $this->account; } /** * Returns data for a connected account based on a search by term * or type (business, user) * * @param $search_term string * @param string $search_type string * * @return array|bool|mixed * * @since 5.10 */ public static function lookup( $search_term, $search_type = 'user' ) { if ( is_array( $search_term ) ) { return false; } if ( $search_type === 'business' ) { if ( $search_term === '' ) { $args = array( 'all_businesses' => true, ); $sources = \InstagramFeed\Builder\SBI_Db::source_query( $args ); if ( empty( $sources ) ) { $sources = \InstagramFeed\Builder\SBI_Db::source_query(); } $connected_accounts = \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources ); $business_accounts = array(); $access_tokens_found = array(); foreach ( $connected_accounts as $connected_account ) { if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' && ! in_array( $connected_account['access_token'], $access_tokens_found, true ) ) { $business_accounts[] = $connected_account; $access_tokens_found[] = $connected_account['access_token']; } } return $business_accounts; } else { $connected_accounts = self::get_all_connected_accounts(); foreach ( $connected_accounts as $connected_account ) { if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) { return $connected_account; } } } } else { $connected_accounts = self::get_all_connected_accounts(); if ( isset( $connected_accounts[ $search_term ] ) ) { return $connected_accounts[ $search_term ]; } else { foreach ( $connected_accounts as $connected_account ) { if ( strpos( $connected_account['access_token'], '.' ) === false ) { if ( strtolower( $connected_account['username'] ) === trim( strtolower( $search_term ) ) ) { return $connected_account; } elseif ( $connected_account['access_token'] === trim( strtolower( $search_term ) ) ) { return $connected_account; } } } } } return false; } /** * Generates a local version of the avatar image file * and stores related information for easy retrieval and * management * * @param $username string * @param $file_name string * * @return bool * * @since 5.10 */ public static function create_local_avatar( $username, $file_name ) { if ( empty( $file_name ) ) { return false; } $options = sbi_get_database_settings(); if ( ! $options['sb_instagram_disable_resize'] ) { $image_editor = wp_get_image_editor( $file_name ); $upload = wp_upload_dir(); $full_file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg'; if ( ! is_wp_error( $image_editor ) ) { $image_editor->set_quality( 80 ); $image_editor->resize( 150, null ); $saved_image = $image_editor->save( $full_file_name ); if ( ! $saved_image ) { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_error( 'image_editor', __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name ); } else { return true; } } else { if ( ! function_exists( 'download_url' ) ) { include_once ABSPATH . 'wp-admin/includes/file.php'; } $timeout_seconds = 5; // Download file to temp dir. $temp_file = download_url( $file_name, $timeout_seconds ); if ( is_wp_error( $image_editor ) ) { return false; } $image_editor = wp_get_image_editor( $temp_file ); global $sb_instagram_posts_manager; $details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name; $sb_instagram_posts_manager->add_error( 'image_editor', $details ); // not uncommon for the image editor to not work using it this way if ( ! is_wp_error( $image_editor ) ) { $image_editor->set_quality( 80 ); $image_editor->resize( 150, null ); $saved_image = $image_editor->save( $full_file_name ); if ( ! $saved_image ) { global $sb_instagram_posts_manager; $details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name; $sb_instagram_posts_manager->add_error( 'image_editor', $details ); } else { return true; } } else { $message = __( 'Error editing image.', 'instagram-feed' ); if ( isset( $image_editor ) && isset( $image_editor->errors ) ) { foreach ( $image_editor->errors as $key => $item ) { $message .= ' ' . $key . ' - ' . $item[0] . ' |'; } if ( isset( $image_editor ) && isset( $image_editor->error_data ) ) { $message .= ' ' . sbi_json_encode( $image_editor->error_data ) . ' |'; } } global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_error( 'image_editor', $message ); } if ( ! empty( $temp_file ) ) { @unlink( $temp_file ); } } } return false; } /** * Whether or not we should attempt to create a local avatar * * @param string $username * * @return bool * * @since 6.0 */ public static function should_create_local_avatar( $username ) { $options = sbi_get_database_settings(); if ( ! $options['sb_instagram_disable_resize'] ) { $avatars = get_option( 'sbi_local_avatars', array() ); return ! isset( $avatars[ $username ] ) || $avatars[ $username ] !== false; } return false; } /** * Delete and update the status of a local avatar * * @param string $username * * @since 6.0 */ public static function delete_local_avatar( $username ) { $upload = wp_upload_dir(); $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg' ); // get all matching images foreach ( $image_files as $file ) { // iterate files if ( is_file( $file ) ) { unlink( $file ); } } self::update_local_avatar_status( $username, 'unset' ); } /** * Whether or not the local avatar file exists * * @param string $username * * @return bool * * @since 6.0 */ public static function local_avatar_exists( $username ) { $avatars = get_option( 'sbi_local_avatars', array() ); return ! empty( $avatars[ $username ] ); } /** * Full URL to local avatar for username * * @param string $username * * @return string * * @since 6.0 */ public static function get_local_avatar_url( $username ) { $avatar_url = sbi_get_resized_uploads_url() . $username . '.jpg'; return $avatar_url; } /** * Store a record of which avatars have been created * * @param string $username * @param string $status * * @since 6.0 */ public static function update_local_avatar_status( $username, $status ) { $avatars = get_option( 'sbi_local_avatars', array() ); if ( $status === 'unset' ) { if ( isset( $avatars[ $username ] ) ) { unset( $avatars[ $username ] ); } } else { $avatars[ $username ] = $status; } update_option( 'sbi_local_avatars', $avatars ); } /** * If an avatar exists, return the URL otherwise try to create one. * If we can't create one or it was not successful, return false. * * @param string $username * @param string $profile_picture * * @return bool|string * * @since 6.0 */ public static function maybe_local_avatar( $username, $profile_picture ) { if ( self::local_avatar_exists( $username ) ) { return self::get_local_avatar_url( $username ); } if ( self::should_create_local_avatar( $username ) ) { $created = self::create_local_avatar( $username, $profile_picture ); self::update_local_avatar_status( $username, $created ); if ( $created ) { return self::get_local_avatar_url( $username ); } } return false; } /** * Encrypt string (access token) with an included initialization vector * * @param string $access_token * @param string $initialization_vector * * @return string * * @since 5.12.4 */ public static function encrypt_access_token( $access_token ) { $encryption = new SB_Instagram_Data_Encryption(); return $encryption->encrypt( $access_token ); } /** * Attempt to decrypt access token * * @param string $access_token * @param string $initialization_vector * * @return string * * @since 5.12.4 */ public static function decrypt_access_token( $access_token ) { $encryption = new SB_Instagram_Data_Encryption(); return $encryption->decrypt( $access_token ); } /** * Encrypt access tokens in a connected account and return it * * @param array $connected_account * * @return mixed * @throws Exception * * @since 5.12.4 */ public static function encrypt_connected_account_tokens( $connected_account ) { if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) { $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] ); $connected_account['access_token'] = $encrypted_access_token; if ( isset( $connected_account['page_access_token'] ) ) { $encrypted_page_access_token = self::encrypt_access_token( $connected_account['page_access_token'] ); $connected_account['page_access_token'] = $encrypted_page_access_token; } $connected_account['wp_user'] = get_current_user_id(); } return $connected_account; } /** * Encrypt all access tokens in all connected accounts. Used for * a one-time update. * * @return array * @throws Exception * * @since 5.12.4 */ public static function encrypt_all_access_tokens() { $options = sbi_get_database_settings(); $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array(); $updated = array(); foreach ( $connected_accounts as $key => $connected_account ) { $updated[ $key ] = $connected_account; if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) { $encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] ); $updated[ $key ]['access_token'] = $encrypted_access_token; if ( isset( $connected_account['page_access_token'] ) ) { $encrypted_page_access_token = self::encrypt_access_token( $connected_account['page_access_token'] ); $updated[ $key ]['page_access_token'] = $encrypted_page_access_token; } $updated[ $key ]['wp_user'] = get_current_user_id(); } } $options['connected_accounts'] = $updated; update_option( 'sb_instagram_settings', $options ); return $connected_accounts; } /** * Returns all connected accounts * * @return array * * @since 6.0 */ public static function get_all_connected_accounts() { $i = 1; $empty_sources = false; $connected_accounts = array(); while ( ! $empty_sources && $i < 20 ) { $sources = \InstagramFeed\Builder\SBI_Db::source_query( array( 'page' => $i ) ); if ( empty( $sources ) ) { $empty_sources = true; } else { $connected_accounts = array_merge( $connected_accounts, \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources ) ); } $i++; } return $connected_accounts; } /** * Update an array of connected accounts * * @return array * * @since 5.14.4 */ public static function update_connected_accounts( $connected_accounts ) { $options = sbi_get_database_settings(); $options['connected_accounts'] = $connected_accounts; update_option( 'sb_instagram_settings', $options ); return $connected_accounts; } } inc/class-sb-instagram-settings.php000064400000141530150515074560013372 0ustar00feed_type_and_terms = array(); $this->connected_accounts_in_feed = array(); $this->atts = $this->filter_atts_for_legacy( $atts ); $this->db = $db; if ( ! empty( $atts['feed'] ) && $atts['feed'] !== 'legacy' ) { $this->settings = SB_Instagram_Settings::get_settings_by_feed_id( $atts['feed'], $preview_settings ); if ( ! empty( $this->settings ) ) { $this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false; $this->settings['feed'] = intval( $atts['feed'] ); $this->connected_accounts = $this->get_connected_accounts_from_settings(); if ( $this->settings['type'] === 'mixed' ) { $this->atts['tagged'] = $this->settings['tagged']; $this->atts['user'] = $this->settings['id']; $this->atts['hashtag'] = $this->settings['hashtag']; } foreach ( $this->atts as $key => $value ) { $this->settings[ $key ] = $value; } } else { return array(); } } if ( empty( $this->settings ) ) { if ( ! empty( $preview_settings ) ) { $this->settings = $preview_settings; } else { $sbi_statuses = get_option( 'sbi_statuses', array() ); if ( ! empty( $sbi_statuses['support_legacy_shortcode'] ) ) { $legacy_settings_option = self::get_legacy_feed_settings(); if ( empty( $legacy_settings_option ) ) { $this->settings = SB_Instagram_Settings::get_settings_by_legacy_shortcode( $atts, $db ); } else { $this->settings = wp_parse_args( $this->atts, $legacy_settings_option ); } } } if ( ! empty( $this->settings ) ) { if ( ! is_array( $this->settings ) ) { $this->settings = array(); } $this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false; $this->settings['feed'] = 'legacy'; $this->connected_accounts = $this->get_connected_accounts_from_settings(); } $this->settings = wp_parse_args( $this->settings, \InstagramFeed\Builder\SBI_Feed_Saver::settings_defaults() ); } if ( empty( $this->settings ) ) { return; } $this->settings = $this->filter_for_builder( $this->settings, $atts ); $this->settings = $this->filter_for_legacy( $this->settings, $atts ); if ( ! empty( $this->settings['customizer'] ) ) { $this->settings = $this->filter_for_customizer( $this->settings ); } if ( empty( $this->settings['feed_is_moderated'] ) ) { $this->settings['feed_is_moderated'] = false; } $this->connected_accounts = apply_filters( 'sbi_connected_accounts', $this->connected_accounts, $this->atts ); $this->settings['customtemplates'] = $this->settings['customtemplates'] === 'true' || $this->settings['customtemplates'] === 'on' || $this->settings['customtemplates'] === true; if ( isset( $_GET['sbi_debug'] ) ) { $this->settings['customtemplates'] = false; } $this->settings['minnum'] = max( (int)$this->settings['num'], (int)$this->settings['nummobile'] ); $this->settings['showbio'] = $this->settings['showbio'] === 'true' || $this->settings['showbio'] === 'on' || $this->settings['showbio'] === true; if ( isset( $this->atts['showbio'] ) && $this->atts['showbio'] === 'false' ) { $this->settings['showbio'] = false; } if ( isset( $this->atts['showheader'] ) && $this->atts['showheader'] === 'false' ) { $this->settings['showheader'] = false; } elseif ( isset( $this->atts['showheader'] ) && $this->atts['showheader'] === 'true' ) { $this->settings['showheader'] = true; } $this->settings['heightunit'] = ! empty( $this->settings['heightunit'] ) ? $this->settings['heightunit'] : 'px'; $this->settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ($db['sb_instagram_disable_resize'] === 'on' || $db['sb_instagram_disable_resize'] === true); $this->settings['favor_local'] = true; $this->settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || $db['sb_instagram_backup'] === 'on' || $db['sb_instagram_backup'] === true; $this->settings['headeroutside'] = ($this->settings['headeroutside'] === true || $this->settings['headeroutside'] === 'on' || $this->settings['headeroutside'] === 'true'); $this->settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ($db['disable_js_image_loading'] === 'on' || $db['disable_js_image_loading'] === true); $this->settings['sb_ajax_initial'] = isset( $db['sb_ajax_initial'] ) && ($db['sb_ajax_initial'] === 'on' || $db['sb_ajax_initial'] === true); $this->settings['ajax_post_load'] = $this->settings['sb_ajax_initial']; switch ( $db['sbi_cache_cron_interval'] ) { case '30mins' : $this->settings['sbi_cache_cron_interval'] = 60*30; break; case '1hour' : $this->settings['sbi_cache_cron_interval'] = 60*60; break; default : $this->settings['sbi_cache_cron_interval'] = 60*60*12; } $this->settings['showfollow'] = ( $this->settings['showfollow'] == 'on' || $this->settings['showfollow'] == 'true' || $this->settings['showfollow'] == true ) && $this->settings['showfollow'] !== 'false'; $this->settings['sb_instagram_cache_time'] = isset( $this->db['sb_instagram_cache_time'] ) ? $this->db['sb_instagram_cache_time'] : 1; $this->settings['sb_instagram_cache_time_unit'] = isset( $this->db['sb_instagram_cache_time_unit'] ) ? $this->db['sb_instagram_cache_time_unit'] : 'hours'; $this->settings['gdpr'] = isset( $this->db['gdpr'] ) ? $this->db['gdpr'] : 'auto'; if ( ! empty( $this->atts['cachetime'] ) ) { $this->settings['caching_type'] = 'page'; $cache_time = max( 1, (int) $this->atts['cachetime'] ); $this->settings['cachetimeseconds'] = 60 * $cache_time; } elseif ( ! empty( $this->db['legacy_page_cache'] ) ) { $this->settings['caching_type'] = 'page'; $cache_time = max( 1, (int) $this->db['legacy_page_cache'] ); $this->settings['cachetimeseconds'] = 60 * $cache_time; } else { $this->settings['caching_type'] = 'background'; } $this->settings['isgutenberg'] = SB_Instagram_Blocks::is_gb_editor(); if ( $this->settings['isgutenberg'] ) { $this->settings['sb_ajax_initial'] = false; $this->settings['disable_js_image_loading'] = true; } if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $this->settings ) ) { SB_Instagram_GDPR_Integrations::init(); } if ( $this->settings['feedid'] === 'false' ) { $this->settings['feedid'] = false; } } public static function legacy_to_builder_convert( $instagram_feed_settings ) { $moderation_json_array = array( 'list_type_selected' => 'allow', 'allow_list' => array(), 'block_list' => ! empty( $instagram_feed_settings['hidephotos'] ) ? explode( ',', str_replace(',', ' ', $instagram_feed_settings['hidephotos'] ) ) : array() ); if ( ! empty( $instagram_feed_settings['whitelist_ids'] ) ) { $moderation_json_array['allow_list'] = $instagram_feed_settings['whitelist_ids']; } else { $moderation_json_array['list_type_selected'] = 'block'; } $instagram_feed_settings['moderationlist'] = json_encode( $moderation_json_array ); $instagram_feed_settings['customizer'] = false; $instagram_feed_settings['feed'] = 'legacy'; $unsets = array( 'feed_is_moderated', 'whitelist_ids', 'whitelist_num', 'minnum', 'disable_resize', 'favor_local', 'backup_cache_enabled', 'font_method', 'disable_js_image_loading', 'sbi_cache_cron_interval', 'sb_instagram_cache_time', 'sb_instagram_cache_time_unit', 'addModerationModeLink', 'caching_type', 'sb_ajax_initial', 'isgutenberg', 'hidephotos', ); foreach ( $unsets as $unset_key ) { if ( isset( $instagram_feed_settings[ $unset_key ] ) ) { unset( $instagram_feed_settings[ $unset_key ] ); } } return $instagram_feed_settings; } public static function get_settings_by_legacy_shortcode( $atts, $db ) { $settings = shortcode_atts( array( 'id' => isset( $db['sb_instagram_user_id'] ) ? $db['sb_instagram_user_id'] : '', 'width' => isset( $db['sb_instagram_width'] ) ? $db['sb_instagram_width'] : '', 'widthunit' => isset( $db['sb_instagram_width_unit'] ) ? $db['sb_instagram_width_unit'] : '', 'widthresp' => isset( $db['sb_instagram_feed_width_resp'] ) ? $db['sb_instagram_feed_width_resp'] : '', 'height' => isset( $db['sb_instagram_height'] ) ? $db['sb_instagram_height'] : '', 'heightunit' => isset( $db['sb_instagram_height_unit'] ) ? $db['sb_instagram_height_unit'] : '', 'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '', 'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '', 'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '', 'nummobile' => isset($db[ 'sb_instagram_nummobile' ]) ? $db[ 'sb_instagram_nummobile' ] : '', 'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '', 'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '', 'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '', 'imagepaddingunit' => isset( $db['sb_instagram_image_padding_unit'] ) ? $db['sb_instagram_image_padding_unit'] : '', 'background' => isset( $db['sb_instagram_background'] ) ? $db['sb_instagram_background'] : '', 'showbutton' => isset( $db['sb_instagram_show_btn'] ) ? $db['sb_instagram_show_btn'] : '', 'buttoncolor' => isset( $db['sb_instagram_btn_background'] ) ? $db['sb_instagram_btn_background'] : '', 'buttontextcolor' => isset( $db['sb_instagram_btn_text_color'] ) ? $db['sb_instagram_btn_text_color'] : '', 'buttontext' => isset( $db['sb_instagram_btn_text'] ) ? $db['sb_instagram_btn_text'] : '', 'imageres' => isset( $db['sb_instagram_image_res'] ) ? $db['sb_instagram_image_res'] : '', 'showfollow' => isset( $db['sb_instagram_show_follow_btn'] ) ? $db['sb_instagram_show_follow_btn'] : '', 'followcolor' => isset( $db['sb_instagram_folow_btn_background'] ) ? $db['sb_instagram_folow_btn_background'] : '', 'followtextcolor' => isset( $db['sb_instagram_follow_btn_text_color'] ) ? $db['sb_instagram_follow_btn_text_color'] : '', 'followtext' => isset( $db['sb_instagram_follow_btn_text'] ) ? $db['sb_instagram_follow_btn_text'] : '', 'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '', 'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '', 'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '', 'custombio' => isset($db[ 'sb_instagram_custom_bio' ]) ? $db[ 'sb_instagram_custom_bio' ] : '', 'customavatar' => isset($db[ 'sb_instagram_custom_avatar' ]) ? $db[ 'sb_instagram_custom_avatar' ] : '', 'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '', 'class' => '', 'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '', 'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '', 'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '', 'headeroutside' => isset($db[ 'sb_instagram_outside_scrollable' ]) ? $db[ 'sb_instagram_outside_scrollable' ] : '', 'accesstoken' => '', 'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false, 'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false, 'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background', 'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '', 'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto', 'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true, ), $atts ); $settings['sources'] = is_string( $settings['id'] ) ? explode( ',', str_replace( ' ', '', $settings['id'] ) ) : array(); return $settings; } /** * Converts settings from the builder to settings used in the feed * * @param $settings * @param $atts * * @return mixed */ public function filter_for_builder( $settings, $atts ) { if ( ! isset( $atts['media'] ) ) { if( isset( $settings['reelsposts'] ) ) { $include_reels = $settings['reelsposts'] !== 'false' && ! empty( $settings['reelsposts'] ) ? true : false; } else { $include_reels = $settings['media'] === 'all' ? true : false; $settings['reelsposts'] = $include_reels ? true : false; } $settings['media'] = $include_reels ? 'all' : array( 'photos', 'videos' ); } else { $include_reels = $settings['media'] === 'all' && strpos( $settings['videotypes'], 'reels' ) !== false; } if ( ! isset( $atts['videotypes'] ) ) { $video_types = array(); if ( $include_reels ) { $video_types[] = 'reels'; $video_types[] = 'regular'; } else { $video_types[] = 'regular'; } $settings['videotypes'] = implode( ',', $video_types ); } if ( isset( $atts['ajaxtheme'] ) ) { $settings['ajaxtheme'] = $atts['ajaxtheme'] === 'true'; } else { $db = sbi_get_database_settings(); $settings['ajaxtheme'] = isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] === '1' || $db['sb_instagram_ajax_theme'] === true || $db['sb_instagram_ajax_theme'] === 'on' : false; } return $settings; } /** * Disables or enables certain settings when using the * customizer * * @param $settings * * @return mixed */ public function filter_for_customizer( $settings ) { $settings['customtemplates'] = false; $settings['moderationmode'] = false; $settings['sb_ajax_initial'] = false; $settings['disable_js_image_loading'] = false; $settings['showheader'] = true; return $settings; } /** * Filters out or converts allowed/disallowed shortcode settings * * @param $atts * * @return mixed */ public function filter_atts_for_legacy( $atts ) { if ( ! empty( $atts['from_update'] ) ) { unset( $atts['from_update'] ); return $atts; } $sbi_statuses = get_option( 'sbi_statuses', array() ); $allowed_legacy_shortcode = array( 'feed', 'headersource', 'customizer', 'class' ); if ( ! empty( $sbi_statuses['support_legacy_shortcode'] ) && empty( $atts['feed'] ) ) { if ( is_array( $sbi_statuses['support_legacy_shortcode'] ) ) { $atts_diff = array_diff( $sbi_statuses['support_legacy_shortcode'], $atts ); // determines if the shortcode settings match the shortcode settings of an existing feed foreach ( $atts_diff as $key => $value ) { if ( in_array( $key, $allowed_legacy_shortcode, true ) ) { unset( $atts_diff[ $key ] ); } } if ( empty( $atts_diff ) ) { $atts['feed'] = 1; } } if ( empty( $atts['feed'] ) ) { return $atts; } } foreach ( $atts as $key => $value ) { if ( ! in_array( $key, $allowed_legacy_shortcode ) ) { unset( $atts[ $key ] ); } } return $atts; } /** * Converts legacy feed settings to work with new settings * * @param $settings * @param $atts * * @return mixed */ public function filter_for_legacy( $settings, $atts ) { return $settings; } public static function get_settings_by_feed_id( $feed_id, $preview_settings = false ) { if ( is_array( $preview_settings ) ) { return $preview_settings; } if ( intval( $feed_id ) < 1 ) { return false; } $feed_saver = new \InstagramFeed\Builder\SBI_Feed_Saver( $feed_id ); return $feed_saver->get_feed_settings(); } public static function get_legacy_feed_settings() { return json_decode( get_option( 'sbi_legacy_feed_settings', '{}' ), true ); } public function feed_type_and_terms_display() { if ( ! isset( $this->feed_type_and_terms ) ) { return array(); } $return = array(); foreach ( $this->feed_type_and_terms as $feed_type => $type_terms ) { foreach ( $type_terms as $term ) { if ( $feed_type === 'users' || $feed_type === 'tagged' ) { if ( ! in_array( $this->connected_accounts_in_feed[ $term['term'] ]['username'], $return, true ) ) { $return[] = $this->connected_accounts_in_feed[ $term['term'] ]['username']; } } elseif ( $feed_type === 'hashtags_recent' || $feed_type === 'hashtags_top' ) { if ( ! in_array( $term['hashtag_name'], $return, true ) ) { $return[] = $term['hashtag_name']; } } } } return $return; } /** * @return array * * @since 2.0/5.0 */ public function get_settings() { return $this->settings; } /** * The plugin will output settings on the frontend for debugging purposes. * Safe settings to display are added here. * * Overwritten in the Pro version. * * @return array * * @since 2.0/5.0 */ public static function get_public_db_settings_keys() { $public = array( 'sb_instagram_user_id', 'sb_instagram_cache_time', 'sb_instagram_cache_time_unit', 'sbi_caching_type', 'sbi_cache_cron_interval', 'sbi_cache_cron_time', 'sbi_cache_cron_am_pm', 'sb_instagram_width', 'sb_instagram_width_unit', 'sb_instagram_feed_width_resp', 'sb_instagram_height', 'sb_instagram_num', 'sb_instagram_height_unit', 'sb_instagram_cols', 'sb_instagram_disable_mobile', 'sb_instagram_image_padding', 'sb_instagram_image_padding_unit', 'sb_instagram_sort', 'sb_instagram_background', 'sb_instagram_show_btn', 'sb_instagram_btn_background', 'sb_instagram_btn_text_color', 'sb_instagram_btn_text', 'sb_instagram_image_res', //Header 'sb_instagram_show_header', 'sb_instagram_header_size', 'sb_instagram_header_color', //Follow button 'sb_instagram_show_follow_btn', 'sb_instagram_folow_btn_background', 'sb_instagram_follow_btn_text_color', 'sb_instagram_follow_btn_text', //Misc 'sb_instagram_cron', 'sb_instagram_backup', 'sb_instagram_ajax_theme', 'sb_instagram_disable_resize', 'disable_js_image_loading', 'enqueue_js_in_head', 'sb_instagram_disable_awesome', 'sb_ajax_initial', 'use_custom' ); return $public; } /** * @return array * * @since 2.0/5.0 */ public function get_connected_accounts() { return $this->connected_accounts; } /** * @return array|bool * * @since 2.0/5.0 */ public function get_connected_accounts_in_feed() { if ( isset( $this->connected_accounts_in_feed ) ) { return $this->connected_accounts_in_feed; } else { return false; } } /** * @return bool|string * * @since 2.0/5.0 */ public function get_transient_name() { if ( isset( $this->transient_name ) ) { return $this->transient_name; } else { return false; } } /** * Uses the feed types and terms as well as as some * settings to create a semi-unique feed id used for * caching and other features. * * Overwritten in the Pro version. * * @param string $transient_name * * @since 2.0/5.0 */ public function set_transient_name( $transient_name = '' ) { if ( ! empty( $transient_name ) ) { $this->transient_name = $transient_name; } elseif ( ! empty( $this->settings['feed'] ) && $this->settings['feed'] !== 'legacy' && intval( $this->settings['feed'] ) > 0 ) { $this->transient_name = '*' . $this->settings['feed']; } elseif ( ! empty( $this->settings['feedid'] ) ) { $this->transient_name = 'sbi_' . $this->settings['feedid']; } else { $feed_type_and_terms = $this->feed_type_and_terms; $sbi_transient_name = 'sbi_'; if ( isset( $feed_type_and_terms['users'] ) ) { foreach ( $feed_type_and_terms['users'] as $term_and_params ) { $user = $term_and_params['term']; $connected_account = isset( $this->connected_accounts_in_feed[ $user ] ) ? $this->connected_accounts_in_feed[ $user ] : array(); if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) { $sbi_transient_name .= $connected_account['username']; } else { $sbi_transient_name .= $user; } } } $num = $this->settings['num']; $num_length = strlen( $num ) + 1; //Add both parts of the caching string together and make sure it doesn't exceed 45 $sbi_transient_name = substr( $sbi_transient_name, 0, 45 - $num_length ); if ( $this->settings['sortby'] === 'random' ) { $sbi_transient_name .= 'rdm'; } $sbi_transient_name .= '#' . $num; $this->transient_name = $sbi_transient_name; } } /** * @return array|bool * * @since 2.0/5.0 */ public function get_feed_type_and_terms() { if ( isset( $this->feed_type_and_terms ) ) { return $this->feed_type_and_terms; } else { return false; } } private function add_connected_accounts_in_feed( $connected_accounts ) { foreach ( $connected_accounts as $key => $connected_account ) { $this->connected_accounts_in_feed[ $key ] = $connected_account; } } private function add_feed_type_and_terms( $feed_type_and_terms ) { $this->feed_type_and_terms = array_merge( $this->feed_type_and_terms, $feed_type_and_terms ); } private function set_user_feed( $users = false ) { global $sb_instagram_posts_manager; if ( ! $users ) { $set = false; if ( empty( $this->connected_accounts ) && empty( $this->settings['feed']) ) { if ( empty( $this->atts['feed'] ) ) { $error_message_return = array( 'error_message' => __( 'Error: No Feed ID Set.', 'instagram-feed' ), 'admin_only' => __( 'Visit the Instagram Feed settings page to see which feeds have been created and how to embed them.', 'instagram-feed' ), 'frontend_directions' => '', 'backend_directions' => '' ); } else { $error_message_return = array( 'error_message' => __( 'Error: Invalid Feed ID.', 'instagram-feed' ), 'admin_only' => __( 'Visit the Instagram Feed settings page to see which feeds have been created and how to embed them.', 'instagram-feed' ), 'frontend_directions' => '', 'backend_directions' => '' ); } $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); return; } foreach ( $this->connected_accounts as $connected_account ) { if ( ! $set ) { $set = true; $this->settings['user'] = $connected_account['username']; $this->connected_accounts_in_feed = array( $connected_account['user_id'] => $connected_account ); $feed_type_and_terms = array( 'users'=> array( array( 'term' => $connected_account['user_id'], 'params' => array() ) ) ); if ( $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) { $feed_type_and_terms['users'][0]['error'] = true; } $this->feed_type_and_terms = $feed_type_and_terms; } } return; } else { $connected_accounts_in_feed = array(); $feed_type_and_terms = array( 'users' => array() ); $usernames_included = array(); $usernames_not_connected = array(); foreach ( $users as $user_id_or_name ) { $connected_account = ! empty( $this->connected_accounts[ $user_id_or_name ] ) ? $this->connected_accounts[ $user_id_or_name ] : SB_Instagram_Connected_Account::lookup( $user_id_or_name ); if ( $connected_account ) { if ( ! in_array( $connected_account['username'], $usernames_included, true ) ) { if ( ! $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) { $feed_type_and_terms['users'][] = array( 'term' => $connected_account['user_id'], 'params' => array() ); } else { $feed_type_and_terms['users'][] = array( 'term' => $connected_account['user_id'], 'params' => array(), 'error' => true ); } $connected_accounts_in_feed[ $connected_account['user_id'] ] = $connected_account; $usernames_included[] = $connected_account['username']; } } else { $feed_type_and_terms['users'][] = array( 'term' => $user_id_or_name, 'params' => array(), 'error' => true ); $usernames_not_connected[] = $user_id_or_name; } } if ( ! empty( $usernames_not_connected ) ) { global $sb_instagram_posts_manager; if ( count( $usernames_not_connected ) === 1 ) { $user = $usernames_not_connected[0]; } else { $user = implode( ', ', $usernames_not_connected ); } $settings_link = '' . __( 'plugin Settings page', 'instagram-feed' ) . ''; $error_message_return = array( 'error_message' => sprintf( __( 'Error: There is no connected account for the user %s.', 'instagram-feed' ), $user ), 'admin_only' => sprintf( __( 'A connected account related to the user is required to display user feeds. Please connect an account for this user on the %s.', 'instagram-feed' ), $settings_link ), 'frontend_directions' => '', 'backend_directions' => '' ); $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); } $this->add_feed_type_and_terms( $feed_type_and_terms ); $this->add_connected_accounts_in_feed( $connected_accounts_in_feed ); } } /** * Based on the settings related to retrieving post data from the API, * this setting is used to make sure all endpoints needed for the feed are * connected and stored for easily looping through when adding posts * * Overwritten in the Pro version. * * @since 2.0/5.0 */ public function set_feed_type_and_terms() { global $sb_instagram_posts_manager; $is_using_access_token_in_shortcode = ! empty( $this->atts['accesstoken'] ); $settings_link = '' . __( 'plugin Settings page', 'instagram-feed' ) . ''; if ( $is_using_access_token_in_shortcode ) { $error_message_return = array( 'error_message' => __( 'Error: Cannot add access token directly to the shortcode.', 'instagram-feed' ), 'admin_only' => sprintf( __( 'Due to recent Instagram platform changes, it\'s no longer possible to create a feed by adding the access token to the shortcode. Remove the access token from the shortcode and connect an account on the %s instead.', 'instagram-feed' ), $settings_link ), 'frontend_directions' => '', 'backend_directions' => '' ); $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); $this->atts['accesstoken'] = ''; } if ( empty( $this->settings['id'] ) && empty( $this->settings['user'] ) && ! empty ( $this->connected_accounts ) ) { $this->set_user_feed(); } else { $user_array = array(); if ( ! empty( $this->settings['user'] ) ) { $user_array = is_array( $this->settings['user'] ) ? $this->settings['user'] : explode( ',', str_replace( ' ', '', $this->settings['user'] ) ); } elseif ( ! empty( $this->settings['id'] ) ) { $user_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) ); } $this->set_user_feed( $user_array ); } if ( empty( $this->feed_type_and_terms['users'] ) ) { $error_message_return = array( 'error_message' => __( 'Error: No users set.', 'instagram-feed' ), 'admin_only' => __( 'Please visit the plugin\'s settings page to select a user account or add one to the shortcode - user="username".', 'instagram-feed' ), 'frontend_directions' => '', 'backend_directions' => '' ); $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); } foreach ( $this->connected_accounts_in_feed as $connected_account_in_feed ) { if ( isset( $connected_account_in_feed['private'] ) && sbi_private_account_near_expiration( $connected_account_in_feed ) ) { $link_1 = ''; $link_2 = ''; $error_message_return = array( 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ), 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %smake your Instagram account public%s.', 'instagram-feed' ), $link_1, $link_2 ), 'frontend_directions' => '' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '', 'backend_directions' => '' ); $sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return ); } } } /** * @return float|int * * @since 2.0/5.0 */ public function get_cache_time_in_seconds() { if ( $this->settings['caching_type'] === 'background' ) { return SBI_CRON_UPDATE_CACHE_TIME; } else { //If the caching time doesn't exist in the database then set it to be 1 hour $cache_time = isset( $this->settings['sb_instagram_cache_time'] ) ? (int)$this->settings['sb_instagram_cache_time'] : 1; $cache_time_unit = isset( $this->settings['sb_instagram_cache_time_unit'] ) ? $this->settings['sb_instagram_cache_time_unit'] : 'hours'; //Calculate the cache time in seconds if ( $cache_time_unit == 'minutes' ) $cache_time_unit = 60; if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60; if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24; $cache_time_return = min( $cache_time * $cache_time_unit, DAY_IN_SECONDS ); return $cache_time_return; } } public static function default_settings() { $defaults = array( 'sb_instagram_at' => '', 'sb_instagram_type' => 'user', 'sb_instagram_order' => 'top', 'sb_instagram_user_id' => '', 'sb_instagram_tagged_ids' => '', 'sb_instagram_hashtag' => '', 'sb_instagram_type_self_likes' => '', 'sb_instagram_location' => '', 'sb_instagram_coordinates' => '', 'sb_instagram_preserve_settings' => '', 'sb_instagram_ajax_theme' => false, 'enqueue_js_in_head' => false, 'disable_js_image_loading' => false, 'sb_instagram_disable_resize' => false, 'sb_instagram_favor_local' => true, 'sb_instagram_cache_time' => '1', 'sb_instagram_cache_time_unit' => 'hours', 'sbi_caching_type' => 'background', 'sbi_cache_cron_interval' => '12hours', 'sbi_cache_cron_time' => '1', 'sbi_cache_cron_am_pm' => 'am', 'sb_instagram_width' => '100', 'sb_instagram_width_unit' => '%', 'sb_instagram_feed_width_resp' => false, 'sb_instagram_height' => '', 'sb_instagram_num' => '20', 'sb_instagram_nummobile' => '', 'sb_instagram_height_unit' => '', 'sb_instagram_cols' => '4', 'sb_instagram_colsmobile' => 'auto', 'sb_instagram_image_padding' => '5', 'sb_instagram_image_padding_unit' => 'px', //Layout Type 'sb_instagram_layout_type' => 'grid', 'sb_instagram_highlight_type' => 'pattern', 'sb_instagram_highlight_offset' => 0, 'sb_instagram_highlight_factor' => 6, 'sb_instagram_highlight_ids' => '', 'sb_instagram_highlight_hashtag' => '', //Hover style 'sb_hover_background' => '', 'sb_hover_text' => '', 'sbi_hover_inc_username' => true, 'sbi_hover_inc_icon' => true, 'sbi_hover_inc_date' => true, 'sbi_hover_inc_instagram' => true, 'sbi_hover_inc_location' => false, 'sbi_hover_inc_caption' => false, 'sbi_hover_inc_likes' => false, // 'sb_instagram_hover_text_size' => '', 'sb_instagram_sort' => 'none', 'sb_instagram_disable_lightbox' => false, 'sb_instagram_captionlinks' => false, 'sb_instagram_background' => '', 'sb_instagram_show_btn' => true, 'sb_instagram_btn_background' => '', 'sb_instagram_btn_text_color' => '', 'sb_instagram_btn_text' => __( 'Load More', 'instagram-feed' ), 'sb_instagram_image_res' => 'auto', 'sb_instagram_media_type' => 'all', 'sb_instagram_moderation_mode' => 'manual', 'sb_instagram_hide_photos' => '', 'sb_instagram_block_users' => '', 'sb_instagram_ex_apply_to' => 'all', 'sb_instagram_inc_apply_to' => 'all', 'sb_instagram_show_users' => '', 'sb_instagram_exclude_words' => '', 'sb_instagram_include_words' => '', //Text 'sb_instagram_show_caption' => true, 'sb_instagram_caption_length' => '50', 'sb_instagram_caption_color' => '', 'sb_instagram_caption_size' => '13', //lightbox comments 'sb_instagram_lightbox_comments' => true, 'sb_instagram_num_comments' => '20', //Meta 'sb_instagram_show_meta' => true, 'sb_instagram_meta_color' => '', 'sb_instagram_meta_size' => '13', //Header 'sb_instagram_show_header' => true, 'sb_instagram_header_color' => '', 'sb_instagram_header_style' => 'standard', 'sb_instagram_show_followers' => true, 'sb_instagram_show_bio' => true, 'sb_instagram_custom_bio' => '', 'sb_instagram_custom_avatar' => '', 'sb_instagram_header_primary_color' => '517fa4', 'sb_instagram_header_secondary_color' => 'eeeeee', 'sb_instagram_header_size' => 'small', 'sb_instagram_outside_scrollable' => false, 'sb_instagram_stories' => true, 'sb_instagram_stories_time' => 5000, //Follow button 'sb_instagram_show_follow_btn' => true, 'sb_instagram_folow_btn_background' => '', 'sb_instagram_follow_btn_text_color' => '', 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ), //Autoscroll 'sb_instagram_autoscroll' => false, 'sb_instagram_autoscrolldistance' => 200, //Misc 'sb_instagram_custom_css' => '', 'sb_instagram_custom_js' => '', 'sb_instagram_requests_max' => '5', 'sb_instagram_minnum' => '0', 'sb_instagram_cron' => 'unset', 'sb_instagram_disable_font' => false, 'sb_instagram_backup' => true, 'sb_ajax_initial' => false, 'enqueue_css_in_shortcode' => false, 'sb_instagram_disable_mob_swipe' => false, 'sbi_br_adjust' => true, 'sb_instagram_media_vine' => false, 'custom_template' => false, 'disable_admin_notice' => false, 'enable_email_report' => 'on', 'email_notification' => 'monday', 'email_notification_addresses' => get_option( 'admin_email' ), //Carousel 'sb_instagram_carousel' => false, 'sb_instagram_carousel_rows' => 1, 'sb_instagram_carousel_loop' => 'rewind', 'sb_instagram_carousel_arrows' => false, 'sb_instagram_carousel_pag' => true, 'sb_instagram_carousel_autoplay' => false, 'sb_instagram_carousel_interval' => '5000' ); return $defaults; } public function get_connected_accounts_from_settings() { if ( $this->settings['feed'] === 'legacy' ) { $sources = \InstagramFeed\Builder\SBI_Db::source_query(); return \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources ); } $include_all_businesses = false; $account_ids = []; if ( $this->settings['type'] === 'hashtag' ) { $include_all_businesses = true; } if ( $this->settings['type'] === 'mixed' ) { $include_all_businesses = ! empty( $this->settings['hashtag'] ); } $ids = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace(' ', '', $this->settings['id'] ) ); $tagged = ! empty( $this->settings['tagged'] ) && is_array( $this->settings['tagged'] ) ? $this->settings['tagged'] : array(); $account_ids = array_merge( $ids, $tagged ); $args = array( 'all_businesses' => $include_all_businesses, 'id' => $account_ids ); $sources = \InstagramFeed\Builder\SBI_Db::source_query( $args ); if ( empty( $sources ) ) { $sources = \InstagramFeed\Builder\SBI_Db::source_query(); } return \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources ); } /** * Compares given array with an allow list of * setting keys and how they should be sanitized * * @param array $atts * * @return array */ public static function sanitize_raw_atts( $atts ) { $sanitized_atts = array(); $allowed_atts = array( 'id' => array( 'method' => 'alpha_numeric_and_comma', 'allowed_vals' => 'any' ), 'width' => array( 'method' => 'page_load_only', ), 'widthunit'=> array( 'method' => 'page_load_only', ), 'widthresp' => array( 'method' => 'page_load_only', ), 'height' => array( 'method' => 'page_load_only', ), 'heightunit' => array( 'method' => 'page_load_only', ), 'sortby' => array( 'method' => 'enum', 'allowed_vals' => array( 'none', 'random', 'likes' ) ), 'num' => array( 'method' => 'intval', 'allowed_vals' => 500 ), 'nummobile' => array( 'method' => 'intval', 'allowed_vals' => 500 ), 'apinum' => array( 'method' => 'intval', 'allowed_vals' => 100 ), 'cols' => array( 'method' => 'intval', 'allowed_vals' => 15 ), 'disablemobile' => array( 'method' => 'page_load_only', ), 'imagepadding' => array( 'method' => 'page_load_only', ), 'imagepaddingunit' => array( 'method' => 'page_load_only', ), 'background' => array( 'method' => 'page_load_only', ), 'showbutton' => array( 'method' => 'page_load_only', ), 'buttoncolor' => array( 'method' => 'page_load_only', ), 'buttontextcolor' => array( 'method' => 'page_load_only', ), 'buttontext' => array( 'method' => 'page_load_only', ), 'imageres' => array( 'method' => 'enum', 'allowed_vals' => array( 'auto', 'thumb', 'low', 'full' ) ), 'showfollow' => array( 'method' => 'page_load_only', ), 'followcolor' => array( 'method' => 'page_load_only', ), 'followtextcolor' => array( 'method' => 'page_load_only', ), 'followtext' => array( 'method' => 'page_load_only', ), 'showheader' => array( 'method' => 'page_load_only', ), 'headersize' => array( 'method' => 'page_load_only', ), 'showbio' => array( 'method' => 'page_load_only', ), 'custombio' => array( 'method' => 'page_load_only', ), 'customavatar' => array( 'method' => 'page_load_only', ), 'headercolor' => array( 'method' => 'page_load_only', ), 'class' => array( 'method' => 'page_load_only', ), 'ajaxtheme' => array( 'method' => 'page_load_only', ), 'cachetime' => array( 'method' => 'page_load_only', ), 'media' => array( 'method' => 'page_load_only', ), 'headeroutside' => array( 'method' => 'page_load_only', ), 'user' => array( 'method' => 'alpha_numeric_and_comma', 'allowed_vals' => 'any' ), 'feedid' => array( 'method' => 'feedid_chars', 'allowed_vals' => 'any' ), 'feed' => array( 'method' => 'alpha_numeric_and_comma', 'allowed_vals' => 'any' ), 'resizeprocess' => array( 'method' => 'enum', 'allowed_vals' => array( 'page', 'background' ) ), 'customtemplates' => array( 'method' => 'string_true', 'allowed_vals' => 'any' ), 'gdpr' => array( 'method' => 'enum', 'allowed_vals' => array( 'auto', 'yes', 'no' ) ) ); foreach ( $atts as $key => $value ) { $value = (string)$value; if ( isset( $allowed_atts[ $key ] ) && strlen( $value ) < 500 ) { $sanitization_method = $allowed_atts[ $key ]['method']; switch ( $sanitization_method ) { case 'enum' : if ( in_array( $value, $allowed_atts[ $key ]['allowed_vals'] ) ) { $sanitized_atts[ $key ] = sanitize_text_field( $value ); } break; case 'alpha_numeric_and_comma' : $sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9,]/", '', $value ); break; case 'feedid_chars' : $sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9#_%-\/?]/", '', urlencode( $value ) ); break; case 'intval' : $value = intval( $value ); if ( $value < (int)$allowed_atts[ $key ]['allowed_vals'] ) { $sanitized_atts[ $key ] = $value; } break; case 'floatval' : $value = floatval( $value ); if ( $allowed_atts[ $key ]['allowed_vals'] === 'any' ) { $sanitized_atts[ $key ] = $value; } elseif ( $value < (float)$allowed_atts[ $key ]['allowed_vals'] ) { $sanitized_atts[ $key ] = $value; } if ( floor( $value ) === $value ) { $sanitized_atts[ $key ] = (int)$value; } break; case 'string_true' : $value = floatval( $value ); if ( $value === 'true' || $value === 'on' || $value === true ) { $sanitized_atts[ $key ] = 'true'; } else { $sanitized_atts[ $key ] = 'false'; } break; } } } return $sanitized_atts; } public static function legacy_shortcode_atts( $atts, $db ) { $settings = shortcode_atts( array( 'id' => isset( $db['sb_instagram_user_id'] ) ? $db['sb_instagram_user_id'] : '', 'width' => isset( $db['sb_instagram_width'] ) ? $db['sb_instagram_width'] : '', 'widthunit' => isset( $db['sb_instagram_width_unit'] ) ? $db['sb_instagram_width_unit'] : '', 'widthresp' => isset( $db['sb_instagram_feed_width_resp'] ) ? $db['sb_instagram_feed_width_resp'] : '', 'height' => isset( $db['sb_instagram_height'] ) ? $db['sb_instagram_height'] : '', 'heightunit' => isset( $db['sb_instagram_height_unit'] ) ? $db['sb_instagram_height_unit'] : '', 'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '', 'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '', 'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '', 'nummobile' => isset( $db['sb_instagram_nummobile'] ) ? $db['sb_instagram_nummobile'] : '', 'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '', 'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '', 'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '', 'imagepaddingunit' => isset( $db['sb_instagram_image_padding_unit'] ) ? $db['sb_instagram_image_padding_unit'] : '', 'background' => isset( $db['sb_instagram_background'] ) ? $db['sb_instagram_background'] : '', 'showbutton' => isset( $db['sb_instagram_show_btn'] ) ? $db['sb_instagram_show_btn'] : '', 'buttoncolor' => isset( $db['sb_instagram_btn_background'] ) ? $db['sb_instagram_btn_background'] : '', 'buttontextcolor' => isset( $db['sb_instagram_btn_text_color'] ) ? $db['sb_instagram_btn_text_color'] : '', 'buttontext' => isset( $db['sb_instagram_btn_text'] ) ? $db['sb_instagram_btn_text'] : '', 'imageres' => isset( $db['sb_instagram_image_res'] ) ? $db['sb_instagram_image_res'] : '', 'showfollow' => isset( $db['sb_instagram_show_follow_btn'] ) ? $db['sb_instagram_show_follow_btn'] : '', 'followcolor' => isset( $db['sb_instagram_folow_btn_background'] ) ? $db['sb_instagram_folow_btn_background'] : '', 'followtextcolor' => isset( $db['sb_instagram_follow_btn_text_color'] ) ? $db['sb_instagram_follow_btn_text_color'] : '', 'followtext' => isset( $db['sb_instagram_follow_btn_text'] ) ? $db['sb_instagram_follow_btn_text'] : '', 'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '', 'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '', 'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '', 'custombio' => isset( $db['sb_instagram_custom_bio'] ) ? $db['sb_instagram_custom_bio'] : '', 'customavatar' => isset( $db['sb_instagram_custom_avatar'] ) ? $db['sb_instagram_custom_avatar'] : '', 'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '', 'class' => '', 'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '', 'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '', 'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '', 'headeroutside' => isset( $db['sb_instagram_outside_scrollable'] ) ? $db['sb_instagram_outside_scrollable'] : '', 'accesstoken' => '', 'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false, 'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false, 'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background', 'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '', 'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto', 'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true, ), $atts ); $settings['customtemplates'] = $settings['customtemplates'] === 'true' || $settings['customtemplates'] === 'on' || $settings['customtemplates'] === true; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['sbi_debug'] ) ) { $settings['customtemplates'] = false; } $settings['minnum'] = max( (int) $settings['num'], (int) $settings['nummobile'] ); $settings['showbio'] = $settings['showbio'] === 'true' || $settings['showbio'] === 'on' || $settings['showbio'] === true; if ( isset( $atts['showbio'] ) && $atts['showbio'] === 'false' ) { $settings['showbio'] = false; } if ( isset( $atts['showheader'] ) && $atts['showheader'] === 'false' ) { $settings['showheader'] = false; } elseif ( isset( $atts['showheader'] ) && $atts['showheader'] === 'true' ) { $settings['showheader'] = true; } $settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ( $db['sb_instagram_disable_resize'] === 'on' || $db['sb_instagram_disable_resize'] === true ); $settings['favor_local'] = true; $settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || ( $db['sb_instagram_backup'] === 'on' ) || $db['sb_instagram_backup'] === true; $settings['headeroutside'] = ( $settings['headeroutside'] === true || $settings['headeroutside'] === 'on' || $settings['headeroutside'] === 'true' ); $settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ( $db['disable_js_image_loading'] === 'on' || $db['disable_js_image_loading'] === true ); $settings['ajax_post_load'] = isset( $db['sb_ajax_initial'] ) && ( $db['sb_ajax_initial'] === 'on' || $db['sb_ajax_initial'] === true ); switch ( $db['sbi_cache_cron_interval'] ) { case '30mins': $settings['sbi_cache_cron_interval'] = 60 * 30; break; case '1hour': $settings['sbi_cache_cron_interval'] = 60 * 60; break; default: $settings['sbi_cache_cron_interval'] = 60 * 60 * 12; } $settings['sb_instagram_cache_time'] = isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : 1; $settings['sb_instagram_cache_time_unit'] = isset( $db['sb_instagram_cache_time_unit'] ) ? $db['sb_instagram_cache_time_unit'] : 'hours'; // use our new colsmobile and colstablet instead of disable mobile if from the DB setting if ( ! empty( $settings['disablemobile'] ) ) { $settings['colstablet'] = $settings['cols']; $settings['colsmobile'] = $settings['cols']; $settings['disablemobile'] = false; } return $settings; } } inc/class-sb-instagram-cron-updater.php000064400000017245150515074560014142 0ustar00 true ) ); $num = count( $cron_records ); if ( $num === \InstagramFeed\Builder\SBI_Db::RESULTS_PER_CRON_UPDATE ) { wp_schedule_single_event( time() + 120, 'sbi_cron_additional_batch' ); } self::update_batch( $cron_records ); } /** * @param $cron_records * * @since 6.0 */ public static function update_batch( $cron_records ) { $report = array( 'notes' => array( 'time_ran' => date( 'Y-m-d H:i:s' ), 'num_found_transients' => count( $cron_records ), ), ); $settings = sbi_get_database_settings(); foreach ( $cron_records as $feed_cache ) { $feed_id = $feed_cache['feed_id']; $report[ $feed_id ] = array(); $cache = new SB_Instagram_Cache( $feed_id ); $cache->retrieve_and_set(); $cache->update_last_updated(); $posts_cache = $cache->get( 'posts' ); if ( $posts_cache ) { $feed_data = json_decode( $posts_cache, true ); $atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : false; $last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int) $feed_data['last_retrieve'] : 0; $last_requested = isset( $feed_data['last_requested'] ) ? (int) $feed_data['last_requested'] : false; $report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve ); if ( $atts !== false ) { // not needed after v6? if ( ! $last_requested || $last_requested > ( time() - 60 * 60 * 24 * 30 ) ) { $instagram_feed_settings = new SB_Instagram_Settings( $atts, $settings ); self::do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts ); $report[ $feed_id ]['did_update'] = 'yes'; } else { $report[ $feed_id ]['did_update'] = 'no - not recently requested'; } } else { $report[ $feed_id ]['did_update'] = 'no - missing atts'; } } else { $report[ $feed_id ]['did_update'] = 'no - no post cache found'; } } update_option( 'sbi_cron_report', $report, false ); } /** * Update a single feed cache based on settings. Local image storing and * resizing is done in the background here as well unless this is the initial * time the feed is created and no cached data exists yet. * * Overwritten in the Pro version * * @param array $instagram_feed_settings associative array generated from * the sb_instagram_settings class * @param array $feed_data post, header, shortcode settings, and other info * associated with the feed that is saved in the cache * @param array $atts shortcode settings * @param bool $include_resize whether or not to resize images during the update since * images can also be resized with an ajax call when the feed is viewed on the frontend * * @return object * * @since 2.0/5.0 */ public static function do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts, $include_resize = true ) { $instagram_feed_settings->set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); $settings = $instagram_feed_settings->get_settings(); $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms(); $instagram_feed = new SB_Instagram_Feed( $transient_name ); $instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings ); while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $to_cache = array( 'atts' => $atts, 'last_requested' => $feed_data['last_requested'], 'last_retrieve' => time() ); $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) { $instagram_feed->set_remote_header_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); $instagram_feed->cache_header_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } if ( $include_resize ) { $post_data = $instagram_feed->get_post_data(); $post_data = array_slice( $post_data, 0, $settings['num'] ); $image_sizes = array( 'personal' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ), 'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ) ); $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name, NULL, $image_sizes ); $post_set->maybe_save_update_and_resize_images_for_posts(); } sbi_delete_image_cache( $transient_name ); return $instagram_feed; } /** * Retrieve option name column values for all feed cache transients * * @return array * * @since 2.0/5.0 */ public static function get_feed_cache_option_names() { global $wpdb; $feed_caches = apply_filters( 'sbi_feed_cache_option_names', array() ); if ( ! empty( $feed_caches ) ) { return $feed_caches; } $results = $wpdb->get_results( " SELECT option_name FROM $wpdb->options WHERE `option_name` LIKE ('%\_transient\_sbi\_%') AND `option_name` NOT LIKE ('%\_transient\_sbi\_header%');", ARRAY_A ); if ( isset( $results[0] ) ) { $feed_caches = $results; } return $feed_caches; } /** * Start cron jobs based on user's settings for cron cache update frequency. * This is triggered when settings are saved on the "Configure" tab. * * @param string $sbi_cache_cron_interval arbitrary name from one of the * settings on the "Configure" tab * @param string $sbi_cache_cron_time hour of the day (1 = 1:00) * @param string $sbi_cache_cron_am_pm am or pm (time of day) * * @since 2.0/5.0 */ public static function start_cron_job( $sbi_cache_cron_interval, $sbi_cache_cron_time, $sbi_cache_cron_am_pm ) { wp_clear_scheduled_hook( 'sbi_feed_update' ); if ( $sbi_cache_cron_interval === '12hours' || $sbi_cache_cron_interval === '24hours' ) { $relative_time_now = time() + sbi_get_utc_offset(); $base_day = strtotime( date( 'Y-m-d', $relative_time_now ) ); $add_time = $sbi_cache_cron_am_pm === 'pm' ? (int)$sbi_cache_cron_time + 12 : (int)$sbi_cache_cron_time; $utc_start_time = $base_day + (($add_time * 60 * 60) - sbi_get_utc_offset()); if ( $utc_start_time < time() ) { if ( $sbi_cache_cron_interval === '12hours' ) { $utc_start_time += 60*60*12; } else { $utc_start_time += 60*60*24; } } if ( $sbi_cache_cron_interval === '12hours' ) { wp_schedule_event( $utc_start_time, 'twicedaily', 'sbi_feed_update' ); } else { wp_schedule_event( $utc_start_time, 'daily', 'sbi_feed_update' ); } } else { if ( $sbi_cache_cron_interval === '30mins' ) { wp_schedule_event( time(), 'sbi30mins', 'sbi_feed_update' ); } else { wp_schedule_event( time(), 'hourly', 'sbi_feed_update' ); } } } } inc/class-sb-instagram-post.php000064400000044476150515074560012532 0ustar00prefix . SBI_INSTAGRAM_POSTS_TYPE; $feed_id_match = $wpdb->get_results( $wpdb->prepare( "SELECT id, media_id, top_time_stamp, images_done FROM $table_name WHERE instagram_id = %s LIMIT 1", $instagram_post_id ), ARRAY_A ); $this->db_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['id'] : ''; $this->media_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['media_id'] : ''; $this->top_time_stamp = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['top_time_stamp'] ) ? $feed_id_match[0]['top_time_stamp'] : ''; $this->images_done = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['images_done'] ) ? $feed_id_match[0]['images_done'] === '1' : 0; $this->instagram_post_id = $instagram_post_id; $this->encryption = new SB_Instagram_Data_Encryption(); } /** * Whether or not this post has already been saved in the custom table * * @return bool * * @since 2.0/4.0 */ public function exists_in_posts_table() { return ! empty( $this->db_id ); } /** * Whether or not resized image files have already been recorded as being created * in the database table * * @return bool|int * * @since 2.0/4.0 */ public function images_done_resizing() { return $this->images_done; } /** * @param array $instagram_api_data * * @since 2.0/4.0 */ public function set_instagram_api_data( $instagram_api_data ) { $this->instagram_api_data = $instagram_api_data; } /** * Used for sorting top posts since they don't have a posted on date * * @return string * * @since 2.0/4.0 */ public function get_top_time_stamp() { return $this->top_time_stamp; } /** * Record newly created images so they can be returned and used right away. * * Not used in version 2.0/5.0 but can be used to resize and use * images "on the fly" when the feed is being displayed. * * @param string $key * @param string $val * * @since 2.0/4.0 */ public function add_resized_image_to_obj_array( $key, $val ) { $this->resized_image_array[ $key ] = $val; } /** * Used to save information about the post before image resizing is done to * prevent a potentially storing multiple entries for the same post * * @param mixed|string|bool $transient_name (optional) * @param null $timestamp_override (optional) * * @return bool * * @since 2.0/4.0 */ public function save_in_db( $transient_name = false, $timestamp_override = null ) { global $wpdb; $parsed_data = $this->get_parsed_post_data(); $timestamp = ! empty( $timestamp_override ) && empty( $parsed_data['timestamp'] ) ? $timestamp_override : $parsed_data['timestamp']; $entry_data = array( "'" . date( 'Y-m-d H:i:s' ) . "'", "'" . esc_sql( $parsed_data['id'] ) . "'", "'" . esc_sql( $timestamp ) . "'", "'" . esc_sql( $timestamp ) . "'", "'" . esc_sql( $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) ) ) . "'", "'pending'", "'pending'", 0, "'" . date( 'Y-m-d H:i:s' ) . "'", ); $entry_string = implode( ',', $entry_data ); $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $timestamp_column = 'time_stamp'; if ( substr( $transient_name, 4, 1 ) === '+' ) { $timestamp_column = 'top_time_stamp'; } $error = $wpdb->query( "INSERT INTO $table_name (created_on,instagram_id,time_stamp,top_time_stamp,json_data,media_id,sizes,images_done,last_requested) VALUES ($entry_string);" ); if ( $error !== false ) { $this->db_id = $wpdb->insert_id; $this->insert_sbi_instagram_feeds_posts( $transient_name ); } else { global $sb_instagram_posts_manager; $error = $wpdb->last_error; $query = $wpdb->last_query; $sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '' ); } return true; } /** * Uses the post's data to get a relevant full size image url and resize it * * @param array $image_sizes * @param string $upload_dir * @param string $upload_url * * @since 2.0/4.0 * @since 2.0/5.0 loop through assoc array (res setting => desired width of image) to * accommodate personal accounts and possible * custom sizes in the future */ public function resize_and_save_image( $image_sizes, $upload_dir, $upload_url ) { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( isset( $this->instagram_api_data['id'] ) ) { $image_source_set = SB_Instagram_Parse::get_media_src_set( $this->instagram_api_data ); $account_type = SB_Instagram_Parse::get_account_type( $this->instagram_api_data ); $image_sizes_to_make = isset( $image_sizes[ $account_type ] ) ? $image_sizes[ $account_type ] : array(); // if it's a personal account or a weird url, the post id is used, otherwise the last part of the image url is used if ( $account_type === 'business' ) { $new_file_name = explode( '?', SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' ) ); if ( strlen( basename( $new_file_name[0], '.jpg' ) ) > 10 ) { $new_file_name = basename( $new_file_name[0], '.jpg' ); } else { $new_file_name = $this->instagram_api_data['id']; } } else { $new_file_name = $this->instagram_api_data['id']; } // the process is considered a success if one image is successfully resized $one_successful_image_resize = false; foreach ( $image_sizes_to_make as $res_setting => $image_size ) { if ( $account_type === 'business' ) { $file_name = SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' ); } else { $file_name = isset( $image_source_set[ $image_size ] ) ? $image_source_set[ $image_size ] : SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' ); } if ( strpos( $file_name, 'placeholder' ) !== false ) { $file_name = ''; } if ( ! empty( $file_name ) ) { $sizes = array( 'height' => 1, 'width' => 1, ); $suffix = $res_setting; $this_image_file_name = $new_file_name . $suffix . '.jpg'; $image_editor = wp_get_image_editor( $file_name ); // If there is an error then lets try a fallback approach if ( is_wp_error( $image_editor ) ) { // Gives us access to the download_url() and wp_handle_sideload() functions. require_once ABSPATH . 'wp-admin/includes/file.php'; $timeout_seconds = 5; // Download file to temp dir. $temp_file = download_url( $file_name, $timeout_seconds ); $image_editor = wp_get_image_editor( $temp_file ); global $sb_instagram_posts_manager; $details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name; $sb_instagram_posts_manager->add_error( 'image_editor', $details ); } // not uncommon for the image editor to not work using it this way if ( ! is_wp_error( $image_editor ) ) { $image_editor->set_quality( 80 ); $sizes = $image_editor->get_size(); $image_editor->resize( $image_size, null ); $full_file_name = trailingslashit( $upload_dir ) . $this_image_file_name; $saved_image = $image_editor->save( $full_file_name ); if ( ! $saved_image ) { global $sb_instagram_posts_manager; $details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name; $sb_instagram_posts_manager->add_error( 'image_editor', $details ); } else { $one_successful_image_resize = true; } } else { $message = __( 'Error editing image.', 'instagram-feed' ); if ( isset( $image_editor ) && isset( $image_editor->errors ) ) { foreach ( $image_editor->errors as $key => $item ) { $message .= ' ' . $key . ' - ' . $item[0] . ' |'; } if ( isset( $image_editor ) && isset( $image_editor->error_data ) ) { $message .= ' ' . sbi_json_encode( $image_editor->error_data ) . ' |'; } } global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_error( 'image_editor', $message ); } if ( ! empty( $temp_file ) ) { @unlink( $temp_file ); } } } if ( $one_successful_image_resize ) { $aspect_ratio = round( $sizes['width'] / $sizes['height'], 2 ); $this->update_sbi_instagram_posts( array( 'media_id' => $new_file_name, 'sizes' => maybe_serialize( $image_sizes_to_make ), 'aspect_ratio' => $aspect_ratio, 'images_done' => 1, ) ); $this->add_resized_image_to_obj_array( 'id', $new_file_name ); } else { // an error status means that image resizing won't be attempted again for this post $this->update_sbi_instagram_posts( array( 'media_id' => 'error', 'sizes' => maybe_serialize( $image_sizes_to_make ), 'aspect_ratio' => 1, 'images_done' => 1, ) ); } } } /** * Return relevant data for resized images for this post * * @return array * * @since 2.0/4.0 */ public function get_resized_image_array() { if ( empty( $this->resized_image_array ) ) { global $wpdb; $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $stored = $wpdb->get_results( $wpdb->prepare( "SELECT media_id, aspect_ratio FROM $posts_table_name WHERE instagram_id = %s LIMIT 1", $this->instagram_post_id ), ARRAY_A ); if ( isset( $stored[0] ) ) { $return = array( 'id' => $stored[0]['media_id'], 'ratio' => $stored[0]['aspect_ratio'], ); $this->resized_image_array = $return; return $return; } else { return array(); } } else { return $this->resized_image_array; } } /** * Controls whether or not the database record will be updated for this post. * Called after images are successfully created. * * @param bool $update_last_requested * @param bool $transient_name * @param array $image_sizes * @param string $upload_dir * @param string $upload_url * @param bool $timestamp_for_update * * @return bool * * @since 2.0/4.0 */ public function update_db_data( $update_last_requested = true, $transient_name = false, $image_sizes = array(), $upload_dir = '', $upload_url = '', $timestamp_for_update = false ) { if ( empty( $this->db_id ) ) { return false; } $to_update = array( 'json_data' => $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) ), ); if ( $update_last_requested ) { $to_update['last_requested'] = date( 'Y-m-d H:i:s' ); } if ( $timestamp_for_update ) { $to_update['top_time_stamp'] = $timestamp_for_update; } if ( $transient_name ) { $this->maybe_add_feed_id( $transient_name ); } if ( $this->media_id === 'pending' ) { $this->resize_and_save_image( $image_sizes, $upload_dir, $upload_url ); } else { $this->update_sbi_instagram_posts( $to_update ); } return true; } /** * Updates columns that need to be updated in the posts types table. * Called after images successfully resized and if any information * needs to be updated. * * @param array $to_update assoc array of columns and values to update * * @since 2.0/4.0 */ public function update_sbi_instagram_posts( $to_update ) { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; foreach ( $to_update as $column => $value ) { $query = $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET $column = %s WHERE id = %d;", $value, $this->db_id ) ); if ( $query === false ) { global $sb_instagram_posts_manager; $error = $wpdb->last_error; $query = $wpdb->last_query; $sb_instagram_posts_manager->add_error( 'storage', __( 'Error updating post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '' ); } } } /** * Checks database for matching record for post and feed ID. * There shouldn't be duplicate records * * @param string $transient_name * * @return bool * * @since 2.0/4.1 */ public function exists_in_feeds_posts_table( $transient_name ) { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; $feed_id_array = explode( '#', $transient_name ); $feed_id = $feed_id_array[0]; $results = $wpdb->get_results( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE instagram_id = %s AND feed_id = %s LIMIT 1", $this->instagram_post_id, $feed_id ), ARRAY_A ); if ( isset( $results[0]['feed_id'] ) ) { return true; } if ( isset( $this->instagram_api_data['term'] ) ) { $results = $wpdb->get_results( $wpdb->prepare( "SELECT hashtag FROM $table_name WHERE instagram_id = %s AND hashtag = %s LIMIT 1", $this->instagram_post_id, strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ), ARRAY_A ); return isset( $results[0]['hashtag'] ); } return false; } /** * Add a record of this post being used for the specified transient name (feed id) * * @param string $transient_name * * @return int * * @since 2.0/4.0 */ public function insert_sbi_instagram_feeds_posts( $transient_name ) { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; // the number is removed from the transient name for backwards compatibilty. $feed_id_array = explode( '#', $transient_name ); $feed_id = $feed_id_array[0]; if ( ! empty( $this->db_id ) ) { $entry_data = array( $this->db_id, "'" . esc_sql( $this->instagram_api_data['id'] ) . "'", "'" . esc_sql( $feed_id ) . "'", ); if ( ! empty( $this->instagram_api_data['term'] ) ) { $entry_data[] = "'" . esc_sql( strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ) . "'"; $entry_string = implode( ',', $entry_data ); $error = $wpdb->query( "INSERT INTO $table_name (id,instagram_id,feed_id,hashtag) VALUES ($entry_string);" ); } else { $entry_string = implode( ',', $entry_data ); $error = $wpdb->query( "INSERT INTO $table_name (id,instagram_id,feed_id) VALUES ($entry_string);" ); } } else { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . __( 'No database ID.', 'instagram-feed' ) ); return false; } if ( $error !== false ) { return $wpdb->insert_id; } else { global $sb_instagram_posts_manager; $error = $wpdb->last_error; $query = $wpdb->last_query; $sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '' ); } } /** * Uses the saved json for the post to be used for updating records * * @param bool $all * * @return array * * @since 2.0/4.0 */ private function get_parsed_post_data( $all = true ) { $instagram_post_id = isset( $this->instagram_api_data['id'] ) ? $this->instagram_api_data['id'] : ''; $comments_count = isset( $this->instagram_api_data['comments_count'] ) ? $this->instagram_api_data['comments_count'] : ''; $like_count = isset( $this->instagram_api_data['like_count'] ) ? $this->instagram_api_data['like_count'] : ''; $parsed_data = array( 'comments_count' => $comments_count, 'like_count' => $like_count, ); if ( $all ) { $caption = isset( $this->instagram_api_data['caption'] ) ? $this->instagram_api_data['caption'] : ''; $media_url = isset( $this->instagram_api_data['media_url'] ) ? $this->instagram_api_data['media_url'] : ''; $media_type = isset( $this->instagram_api_data['media_type'] ) ? $this->instagram_api_data['media_type'] : ''; $timestamp = ''; if ( isset( $this->instagram_api_data['timestamp'] ) ) { $timestamp_parts = explode( ' ', $this->instagram_api_data['timestamp'] ); $timestamp = str_replace( 'T', ' ', $timestamp_parts[0] ); } $username = isset( $this->instagram_api_data['username'] ) ? $this->instagram_api_data['username'] : ''; $permalink = isset( $this->instagram_api_data['permalink'] ) ? $this->instagram_api_data['permalink'] : ''; $children = isset( $this->instagram_api_data['children'] ) ? sbi_json_encode( $this->instagram_api_data['children'] ) : ''; $parsed_data['caption'] = $caption; $parsed_data['media_url'] = $media_url; $parsed_data['id'] = $instagram_post_id; $parsed_data['media_type'] = $media_type; $parsed_data['timestamp'] = $timestamp; $parsed_data['username'] = $username; $parsed_data['permalink'] = $permalink; $parsed_data['children'] = $children; } return $parsed_data; } /** * If a record hasn't been made for this transient name/feed id, * make a record * * @param string $feed_id * * @since 2.0/4.0 */ private function maybe_add_feed_id( $feed_id ) { if ( empty( $this->instagram_post_id ) ) { return; } global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; // the number is removed from the transient name for backwards compatibilty. $feed_id_array = explode( '#', $feed_id ); $feed_id = str_replace( '+', '', $feed_id_array[0] ); $feed_id_match = $wpdb->get_col( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE feed_id = %s AND instagram_id = %s", $feed_id, $this->instagram_post_id ) ); if ( ! isset( $feed_id_match[0] ) ) { $entry_data = array( $this->db_id, "'" . esc_sql( $this->instagram_post_id ) . "'", "'" . esc_sql( $feed_id ) . "'", ); $entry_string = implode( ',', $entry_data ); $error = $wpdb->query( "INSERT INTO $table_name (id,instagram_id,feed_id) VALUES ($entry_string);" ); } } } inc/class-sb-instagram-gdpr-integrations.php000064400000014566150515074560015202 0ustar00prefix . SBI_INSTAGRAM_POSTS_TYPE; $sbi_statuses_option['gdpr']['tables'] = true; if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) { $sbi_statuses_option['gdpr']['tables'] = false; } $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) !== $feeds_posts_table_name ) { $sbi_statuses_option['gdpr']['tables'] = false; } update_option( 'sbi_statuses', $sbi_statuses_option ); } if ( $retest ) { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_action_log( 'Retesting GDPR features.' ); } if ( ! $sbi_statuses_option['gdpr']['upload_dir'] || ! $sbi_statuses_option['gdpr']['tables'] || ! $sbi_statuses_option['gdpr']['image_editor'] ) { return false; } return true; } public static function gdpr_tests_error_message() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $errors = array(); if ( ! $sbi_statuses_option['gdpr']['upload_dir'] ) { $errors[] = __( 'A folder for storing resized images was not successfully created.', 'instagram-feed' ); } if ( ! $sbi_statuses_option['gdpr']['tables'] ) { $errors[] = __( 'Tables used for storing information about resized images were not successfully created.', 'instagram-feed' ); } if ( ! $sbi_statuses_option['gdpr']['image_editor'] ) { $errors[] = sprintf( __( 'An image editor is not available on your server. Instagram Feed is unable to create local resized images. See %1$sthis FAQ%2$s for more information', 'instagram-feed' ), '', '' ); } if ( isset( $_GET['tab'] ) && $_GET['tab'] !== 'support' ) { $tab = sbi_is_pro_version() ? 'customize-advanced' : 'customize'; $errors[] = '' . __( 'Retest', 'instagram-feed' ) . ''; } return implode( '
', $errors ); } public static function statuses() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $return = isset( $sbi_statuses_option['gdpr'] ) ? $sbi_statuses_option['gdpr'] : array(); return $return; } } inc/class-sb-instagram-oembed.php000064400000022250150515074560012762 0ustar00' . str_replace( 'class="instagram-media"', 'class="instagram-media sbi-embed"', $html ) . '
'; } } return $html; } /** * Extend the "time to live" for oEmbeds created with access tokens that expire * * @param $ttl * @param $url * @param $attr * @param $post_ID * * @return float|int * * @since 2.5/5.8 */ public static function oembed_ttl( $ttl, $url, $attr, $post_ID ) { if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv|reel)/.*#i', $url ) === 1 ) { $ttl = 30 * YEAR_IN_SECONDS; } return $ttl; } /** * Depending on whether a business or personal account is connected, * a different oembed endpoint is used * * @return bool|string * * @since 2.5/5.8 */ public static function oembed_url() { return 'https://graph.facebook.com/v8.0/instagram_oembed'; } /** * Any access token will work for oembeds so the most recently connected account's * access token is returned * * @return bool|string * * @since 2.5/5.8 */ public static function last_access_token() { $oembed_token_settings = get_option( 'sbi_oembed_token', array() ); $will_expire = SB_Instagram_Oembed::oembed_access_token_will_expire(); if ( ! empty( $oembed_token_settings['access_token'] ) && (! $will_expire || $will_expire > time()) ) { $return = sbi_maybe_clean( $oembed_token_settings['access_token'] ); return $return; } else { $if_database_settings = sbi_get_database_settings(); if ( isset( $if_database_settings['connected_accounts'] ) ) { $connected_accounts = $if_database_settings['connected_accounts']; foreach ( $connected_accounts as $connected_account ) { if ( empty( $oembed_token_settings['access_token'] ) ) { if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) { $oembed_token_settings['access_token'] = $connected_account['access_token']; } } } } if ( ! empty( $oembed_token_settings['access_token'] ) ) { $return = sbi_maybe_clean( $oembed_token_settings['access_token'] ); return $return; } if ( class_exists( 'CFF_Oembed' ) ) { $cff_oembed_token_settings = get_option( 'cff_oembed_token', array() ); if ( ! empty( $cff_oembed_token_settings['access_token'] ) ) { return $cff_oembed_token_settings['access_token']; } } } return false; } /** * Access tokens created from FB accounts not connected to an * FB page expire after 60 days. * * @return bool|int */ public static function oembed_access_token_will_expire() { $oembed_token_settings = get_option( 'sbi_oembed_token', array() ); $will_expire = isset( $oembed_token_settings['expiration_date'] ) && (int)$oembed_token_settings['expiration_date'] > 0 ? (int)$oembed_token_settings['expiration_date'] : false; return $will_expire; } /** * Before links in the content are processed, old oembed post meta * records are deleted so new oembed data will be retrieved and saved. * If this check has been done and no old oembeds are found, a flag * is saved as post meta to skip the process. * * @since 2.5/5.8 */ public static function check_page_for_old_oembeds() { if ( is_admin() ) { return; } $post_ID = get_the_ID(); $done_checking = (int)get_post_meta( $post_ID, '_sbi_oembed_done_checking', true ) === 1; if ( ! $done_checking ) { $num_found = SB_Instagram_Oembed::delete_instagram_oembed_caches( $post_ID ); if ( $num_found === 0 ) { update_post_meta( $post_ID, '_sbi_oembed_done_checking', 1 ); } } } /** * Loop through post meta data and if it's an oembed and has content * that looks like an Instagram oembed, delete it * * @param $post_ID * * @return int number of old oembed caches found * * @since 2.5/5.8 */ public static function delete_instagram_oembed_caches( $post_ID ) { $post_metas = get_post_meta( $post_ID ); if ( empty( $post_metas ) ) { return 0; } $total_found = 0; foreach ( $post_metas as $post_meta_key => $post_meta_value ) { if ( '_oembed_' === substr( $post_meta_key, 0, 8 ) ) { if ( strpos( $post_meta_value[0], 'class="instagram-media"' ) !== false && strpos( $post_meta_value[0], 'sbi-embed-wrap' ) === false ) { $total_found++; delete_post_meta( $post_ID, $post_meta_key ); if ( '_oembed_time_' !== substr( $post_meta_key, 0, 13 ) ) { delete_post_meta( $post_ID, str_replace( '_oembed_', '_oembed_time_', $post_meta_key ) ); } } } } return $total_found; } /** * Used for clearing the oembed update check flag for all posts * * @since 2.5/5.8 */ public static function clear_checks() { global $wpdb; $table_name = esc_sql( $wpdb->prefix . "postmeta" ); $result = $wpdb->query(" DELETE FROM $table_name WHERE meta_key = '_sbi_oembed_done_checking';"); } } function sbiOembedInit() { return new SB_Instagram_Oembed(); } sbiOembedInit();inc/if-functions.php000064400000166447150515074560010464 0ustar00get_settings();; if ( empty( $early_settings ) && ! sbi_doing_customizer( $atts ) ) { $style = current_user_can( 'manage_instagram_feed_options' ) ? ' style="display: block;"' : ''; $id = isset( $atts['feed'] ) ? (int)$atts['feed'] : false; if ( $id ) { $message = sprintf( __( 'Error: No feed with the ID %s found.', 'instagram-feed' ), $id ); } else { $message = __( 'Error: No feed found.', 'instagram-feed' ); } ob_start(); ?>
>

set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); $settings = $instagram_feed_settings->get_settings(); $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms(); $instagram_feed = new SB_Instagram_Feed( $transient_name ); $instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings ); if ( $settings['caching_type'] === 'background' ) { $instagram_feed->add_report( 'background caching used' ); if ( $instagram_feed->regular_cache_exists() ) { $instagram_feed->add_report( 'setting posts from cache' ); $instagram_feed->set_post_data_from_cache(); } if ( $instagram_feed->need_to_start_cron_job() ) { $instagram_feed->add_report( 'setting up feed for cron cache' ); $to_cache = array( 'atts' => $atts, 'last_requested' => time(), ); $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() ); SB_Instagram_Cron_Updater::do_single_feed_cron_update( $instagram_feed_settings, $to_cache, $atts, false ); $instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings ); $instagram_feed->set_post_data_from_cache(); } elseif ( $instagram_feed->should_update_last_requested() ) { $instagram_feed->add_report( 'updating last requested' ); $to_cache = array( 'last_requested' => time(), ); $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } elseif ( $instagram_feed->regular_cache_exists() ) { $instagram_feed->add_report( 'page load caching used and regular cache exists' ); $instagram_feed->set_post_data_from_cache(); if ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } else { $instagram_feed->add_report( 'no feed cache found' ); while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } if ( ! $instagram_feed->should_use_backup() ) { $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } if ( $instagram_feed->should_use_backup() ) { $instagram_feed->add_report( 'trying to use backup' ); $instagram_feed->maybe_set_post_data_from_backup(); $instagram_feed->maybe_set_header_data_from_backup(); } // if need a header if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) { if ( $instagram_feed->should_use_backup() && $settings['minnum'] > 0 ) { $instagram_feed->add_report( 'trying to set header from backup' ); $header_cache_success = $instagram_feed->maybe_set_header_data_from_backup(); } elseif ( $instagram_feed->regular_header_cache_exists() ) { // set_post_data_from_cache $instagram_feed->add_report( 'page load caching used and regular header cache exists' ); $instagram_feed->set_header_data_from_cache(); } else { $instagram_feed->add_report( 'no header cache exists' ); $instagram_feed->set_remote_header_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); $instagram_feed->cache_header_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } else { $instagram_feed->add_report( 'no header needed' ); } if ( $settings['resizeprocess'] === 'page' ) { $instagram_feed->add_report( 'resizing images for post set' ); $post_data = $instagram_feed->get_post_data(); $post_data = array_slice( $post_data, 0, $settings['num'] ); $post_set = new SB_Instagram_Post_Set( $post_data, $transient_name ); $post_set->maybe_save_update_and_resize_images_for_posts(); } if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) { global $sb_instagram_posts_manager; $post_data = $instagram_feed->get_post_data(); if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) { $image_ids = array(); foreach ( $post_data as $post ) { $image_ids[] = SB_Instagram_Parse::get_post_id( $post ); } $resized_images = SB_Instagram_Feed::get_resized_images_source_set( $image_ids, 0, $transient_name ); $instagram_feed->set_resized_images( $resized_images ); } } return $instagram_feed->get_the_feed_html( $settings, $atts, $instagram_feed_settings->get_feed_type_and_terms(), $instagram_feed_settings->get_connected_accounts_in_feed() ); } /** * For efficiency, local versions of image files available for the images actually displayed on the page * are added at the end of the feed. * * @param object $instagram_feed * @param string $feed_id */ function sbi_add_resized_image_data( $instagram_feed, $feed_id ) { global $sb_instagram_posts_manager; if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) { if ( $instagram_feed->should_update_last_requested() ) { SB_Instagram_Feed::update_last_requested( $instagram_feed->get_image_ids_post_set() ); } } ?> set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); if ( $transient_name !== $feed_id ) { die( 'id does not match' ); } $settings = $instagram_feed_settings->get_settings(); $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown'; $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown'; $feed_details = array( 'feed_id' => $transient_name, 'atts' => $atts, 'location' => array( 'post_id' => $post_id, 'html' => $location ) ); $can_do_background_tasks = false; if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { $nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : ''; if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) { $can_do_background_tasks = true; } } else { $can_do_background_tasks = true; } if ( $can_do_background_tasks ) { sbi_do_background_tasks( $feed_details ); } $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms(); $instagram_feed = new SB_Instagram_Feed( $transient_name ); $instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings ); if ( $settings['caching_type'] === 'background' ) { $instagram_feed->add_report( 'background caching used' ); if ( $instagram_feed->regular_cache_exists() ) { $instagram_feed->add_report( 'setting posts from cache' ); $instagram_feed->set_post_data_from_cache(); } if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) { while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $normal_method = true; if ( $instagram_feed->need_to_start_cron_job() ) { $instagram_feed->add_report( 'needed to start cron job' ); $to_cache = array( 'atts' => $atts, 'last_requested' => time(), ); $normal_method = false; } else { $instagram_feed->add_report( 'updating last requested and adding to cache' ); $to_cache = array( 'last_requested' => time(), ); } if ( $normal_method ) { $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } else { $instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() ); } } } elseif ( $instagram_feed->regular_cache_exists() ) { $instagram_feed->add_report( 'regular cache exists' ); $instagram_feed->set_post_data_from_cache(); if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) { while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $instagram_feed->add_report( 'adding to cache' ); $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } else { $instagram_feed->add_report( 'no feed cache found' ); while ( $instagram_feed->need_posts( $settings['num'], $offset ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } if ( $instagram_feed->should_use_backup() ) { $instagram_feed->add_report( 'trying to use a backup cache' ); $instagram_feed->maybe_set_post_data_from_backup(); } else { $instagram_feed->add_report( 'transient gone, adding to cache' ); $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) { global $sb_instagram_posts_manager; $post_data = array_slice( $instagram_feed->get_post_data(), $offset, $settings['minnum'] ); if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) { $image_ids = array(); foreach ( $post_data as $post ) { $image_ids[] = SB_Instagram_Parse::get_post_id( $post ); } $resized_images = SB_Instagram_Feed::get_resized_images_source_set( $image_ids, 0, $feed_id ); $instagram_feed->set_resized_images( $resized_images ); } } $feed_status = array( 'shouldPaginate' => $instagram_feed->should_use_pagination( $settings, $offset ) ); $return = array( 'html' => $instagram_feed->get_the_items_html( $settings, $offset, $instagram_feed_settings->get_feed_type_and_terms(), $instagram_feed_settings->get_connected_accounts_in_feed() ), 'feedStatus' => $feed_status, 'report' => $instagram_feed->get_report(), 'resizedImages' => SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 1, $feed_id ) ); header( 'Content-Type: application/json; charset=utf-8' ); echo sbi_json_encode( $return ); die(); } add_action( 'wp_ajax_sbi_load_more_clicked', 'sbi_get_next_post_set' ); add_action( 'wp_ajax_nopriv_sbi_load_more_clicked', 'sbi_get_next_post_set' ); /** * Posts that need resized images are processed after being sent to the server * using AJAX * * @return string */ function sbi_process_submitted_resize_ids() { if ( ! sbi_current_user_can( 'manage_instagram_feed_options') ) { if ( ! isset( $_POST['feed_id'] ) || (strpos( $_POST['feed_id'], 'sbi' ) === false && strpos( $_POST['feed_id'], '*' ) === false ) ) { die( 'invalid feed ID'); } } $feed_id = sanitize_text_field( $_POST['feed_id'] ); $images_need_resizing_raw = isset( $_POST['needs_resizing'] ) ? $_POST['needs_resizing'] : array(); if ( is_array( $images_need_resizing_raw ) ) { array_map( 'sbi_sanitize_instagram_ids', $images_need_resizing_raw ); } else { $images_need_resizing_raw = array(); } $images_need_resizing = $images_need_resizing_raw; $atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array(); if ( is_array( $atts_raw ) ) { $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw ); } else { $atts_raw = array(); } $atts = $atts_raw; // now sanitized $offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0; $cache_all = isset( $_POST['cache_all'] ) ? $_POST['cache_all'] === 'true' : false; $database_settings = sbi_get_database_settings(); $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings ); $instagram_feed_settings->set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); $settings = $instagram_feed_settings->get_settings(); $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown'; $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown'; $feed_details = array( 'feed_id' => $transient_name, 'atts' => $atts, 'location' => array( 'post_id' => $post_id, 'html' => $location ) ); $can_do_background_tasks = false; if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { $nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : ''; if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) { $can_do_background_tasks = true; } } else { $can_do_background_tasks = true; } if ( $can_do_background_tasks ) { sbi_do_background_tasks( $feed_details ); } if ( $cache_all ) { $settings['cache_all'] = true; } if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { if ( $transient_name !== $feed_id ) { die( 'id does not match' ); } } sbi_resize_posts_by_id( $images_need_resizing, $transient_name, $settings ); sbi_delete_image_cache( $transient_name ); global $sb_instagram_posts_manager; if ( ! $sb_instagram_posts_manager->image_resizing_disabled( $transient_name ) ) { $num = $settings['minnum'] * 2 + 5; header( 'Content-Type: application/json; charset=utf-8' ); echo sbi_json_encode( SB_Instagram_Feed::get_resized_images_source_set( $num, $offset - $settings['minnum'], $feed_id, false ) ); die(); } die( 'resizing success' ); } add_action( 'wp_ajax_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' ); add_action( 'wp_ajax_nopriv_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' ); function sbi_do_locator() { if ( ! sbi_current_user_can( 'manage_instagram_feed_options') ) { if ( ! isset( $_POST['feed_id'] ) || (strpos( $_POST['feed_id'], 'sbi' ) === false && strpos( $_POST['feed_id'], '*' ) === false ) ) { die( 'invalid feed ID'); } } $feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) ); $atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array(); if ( is_array( $atts_raw ) ) { $atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw ); } else { $atts_raw = array(); } $atts = $atts_raw; // now sanitized $database_settings = sbi_get_database_settings(); $instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings ); $instagram_feed_settings->set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); $location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown'; $post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown'; $feed_details = array( 'feed_id' => $feed_id, 'atts' => $atts, 'location' => array( 'post_id' => $post_id, 'html' => $location ) ); $can_do_background_tasks = false; if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { $nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : ''; if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) { $can_do_background_tasks = true; } } else { $can_do_background_tasks = true; } if ( $can_do_background_tasks ) { sbi_do_background_tasks( $feed_details ); wp_die( 'locating success' ); } wp_die( 'skipped locating' ); } add_action( 'wp_ajax_sbi_do_locator', 'sbi_do_locator' ); add_action( 'wp_ajax_nopriv_sbi_do_locator', 'sbi_do_locator' ); function sbi_do_background_tasks( $feed_details ) { if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] === 'sbi-feed-builder') { return; } $locator = new SB_Instagram_Feed_Locator( $feed_details ); $locator->add_or_update_entry(); if ( $locator->should_clear_old_locations() ) { $locator->delete_old_locations(); } } /** * Outputs an organized error report for the front end. * This hooks into the end of the feed before the closing div * * @param object $instagram_feed * @param string $feed_id */ function sbi_error_report( $instagram_feed, $feed_id ) { global $sb_instagram_posts_manager; if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { $sb_instagram_posts_manager->reset_frontend_errors(); return; } $error_messages = $sb_instagram_posts_manager->get_frontend_errors( $instagram_feed ); if ( ! empty( $error_messages ) ) {?>

' . esc_html( $error_message['error_message'] ) . ''; if ( sbi_current_user_can( 'manage_instagram_feed_options' ) ) { echo '
' . $error_message['admin_only']; echo '
' . $error_message['frontend_directions']; } echo '
'; } ?>
reset_frontend_errors(); } add_action( 'sbi_before_feed_end', 'sbi_error_report', 10, 2 ); function sbi_delete_image_cache( $transient_name ) { $cache = new SB_Instagram_Cache( $transient_name ); $cache->clear( 'resized_images' ); } function sbi_current_user_can( $cap ) { if ( $cap === 'manage_instagram_feed_options' ) { $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; } $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); return current_user_can( $cap ); } function sbi_doing_openssl() { return extension_loaded( 'openssl' ); } /** * Debug report added at the end of the feed when sbi_debug query arg is added to a page * that has the feed on it. * * @param object $instagram_feed * @param string $feed_id */ function sbi_debug_report( $instagram_feed, $feed_id ) { if ( ! isset( $_GET['sbi_debug'] ) && ! isset( $_GET['sb_debug'] ) ) { return; } global $sb_instagram_posts_manager; $feed = $instagram_feed->get_feed_id(); $atts = array(); if ( ! empty( $feed ) ) { $atts = array( 'feed' => 1 ); } $settings_obj = new SB_Instagram_Settings( $atts, sbi_get_database_settings() ); $settings = $settings_obj->get_settings(); $public_settings_keys = SB_Instagram_Settings::get_public_db_settings_keys(); ?>

Status

Settings

GDPR

$settings['custombgcolor1'], 'text1' => $settings['customtextcolor1'], 'text2' => $settings['customtextcolor2'], 'link1' => $settings['customlinkcolor1'], 'button1' => $settings['custombuttoncolor1'], 'button2' => $settings['custombuttoncolor2'] ); ?> set_cache( MONTH_IN_SECONDS, $settings ); if ( $instagram_feed->regular_cache_exists() ) { // set_post_data_from_cache $instagram_feed->set_post_data_from_cache(); $cached_post_data = $instagram_feed->get_post_data(); } elseif ( sbi_current_user_can( 'manage_instagram_feed_options' ) && is_admin() ) { $customizer_cache = new SB_Instagram_Cache( $transient_name, 1, MONTH_IN_SECONDS ); $cached_post_data = $customizer_cache->get_customizer_cache(); } else { return array(); } if ( ! isset( $settings['cache_all'] ) || ! $settings['cache_all'] ) { $num_ids = count( $ids ); $found_posts = array(); $i = 0; while ( count( $found_posts) < $num_ids && isset( $cached_post_data[ $i ] ) ) { if ( ! empty( $cached_post_data[ $i ]['id'] ) && in_array( $cached_post_data[ $i ]['id'], $ids, true ) ) { $found_posts[] = $cached_post_data[ $i ]; } $i++; } } else { $found_posts = array_slice( $cached_post_data, 0, 50 ); } $fill_in_timestamp = date( 'Y-m-d H:i:s', time() + 120 ); if ( $offset !== 0 ) { $fill_in_timestamp = date( 'Y-m-d H:i:s', strtotime( $instagram_feed->get_earliest_time_stamp( $transient_name ) ) - 120 ); } $image_sizes = array( 'personal' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ), 'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ) ); $post_set = new SB_Instagram_Post_Set( $found_posts, $transient_name, $fill_in_timestamp, $image_sizes ); $post_set->maybe_save_update_and_resize_images_for_posts(); } function sbi_create_local_avatar( $username, $file_name ) { return SB_Instagram_Connected_Account::create_local_avatar( $username, $file_name ); } /** * Get the settings in the database with defaults * * @return array */ function sbi_get_database_settings() { $defaults = array( 'sb_instagram_at' => '', 'sb_instagram_user_id' => '', 'sb_instagram_preserve_settings' => '', 'sb_instagram_ajax_theme' => false, 'sb_instagram_disable_resize' => false, 'sb_instagram_cache_time' => 1, 'sb_instagram_cache_time_unit' => 'hours', 'sbi_caching_type' => 'background', 'sbi_cache_cron_interval' => '12hours', 'sbi_cache_cron_time' => '1', 'sbi_cache_cron_am_pm' => 'am', 'sb_instagram_width' => '100', 'sb_instagram_width_unit' => '%', 'sb_instagram_feed_width_resp' => false, 'sb_instagram_height' => '', 'sb_instagram_num' => '20', 'sb_instagram_height_unit' => '', 'sb_instagram_cols' => '4', 'sb_instagram_disable_mobile' => false, 'sb_instagram_image_padding' => '5', 'sb_instagram_image_padding_unit' => 'px', 'sb_instagram_sort' => 'none', 'sb_instagram_background' => '', 'sb_instagram_show_btn' => true, 'sb_instagram_btn_background' => '', 'sb_instagram_btn_text_color' => '', 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ), 'sb_instagram_image_res' => 'auto', //Header 'sb_instagram_show_header' => true, 'sb_instagram_header_size' => 'small', 'sb_instagram_header_color' => '', //Follow button 'sb_instagram_show_follow_btn' => true, 'sb_instagram_folow_btn_background' => '', 'sb_instagram_follow_btn_text_color' => '', 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ), //Misc 'sb_instagram_custom_css' => '', 'sb_instagram_custom_js' => '', 'sb_instagram_cron' => 'no', 'sb_instagram_backup' => true, 'sb_ajax_initial' => false, 'enqueue_css_in_shortcode' => false, 'sb_instagram_disable_mob_swipe' => false, 'sb_instagram_disable_awesome' => false ); $sbi_settings = get_option( 'sb_instagram_settings', array() ); return array_merge( $defaults, $sbi_settings ); } /** * May include support for templates in theme folders in the future * * @since 2.1 custom templates supported */ function sbi_get_feed_template_part( $part, $settings = array() ) { $file = ''; $using_custom_templates_in_theme = apply_filters( 'sbi_use_theme_templates', $settings['customtemplates'] ); $generic_path = trailingslashit( SBI_PLUGIN_DIR ) . 'templates/'; if ( $using_custom_templates_in_theme ) { $custom_header_template = locate_template( 'sbi/header.php', false, false ); $custom_item_template = locate_template( 'sbi/item.php', false, false ); $custom_footer_template = locate_template( 'sbi/footer.php', false, false ); $custom_feed_template = locate_template( 'sbi/feed.php', false, false ); } else { $custom_header_template = false; $custom_item_template = false; $custom_footer_template = false; $custom_feed_template = false; } if ( $part === 'header' ) { if ( $custom_header_template ) { $file = $custom_header_template; } else { $file = $generic_path . 'header.php'; } } elseif ( $part === 'item' ) { if ( $custom_item_template ) { $file = $custom_item_template; } else { $file = $generic_path . 'item.php'; } } elseif ( $part === 'footer' ) { if ( $custom_footer_template ) { $file = $custom_footer_template; } else { $file = $generic_path . 'footer.php'; } } elseif ( $part === 'feed' ) { if ( $custom_feed_template ) { $file = $custom_feed_template; } else { $file = $generic_path . 'feed.php'; } } return $file; } /** * Triggered by a cron event to update feeds */ function sbi_cron_updater() { $cron_updater = new SB_Instagram_Cron_Updater(); $cron_updater->do_feed_updates(); sbi_do_background_tasks( array() ); } add_action( 'sbi_feed_update', 'sbi_cron_updater' ); /** * @param $maybe_dirty * * @return string */ function sbi_maybe_clean( $maybe_dirty ) { $encryption = new SB_Instagram_Data_Encryption(); $decrypted = $encryption->decrypt( $maybe_dirty ); if ( $decrypted ) { $maybe_dirty = $decrypted; } if ( substr_count ( $maybe_dirty , '.' ) < 3 ) { return str_replace( '634hgdf83hjdj2', '', $maybe_dirty ); } $parts = explode( '.', trim( $maybe_dirty ) ); $last_part = $parts[2] . $parts[3]; $cleaned = $parts[0] . '.' . base64_decode( $parts[1] ) . '.' . base64_decode( $last_part ); return $cleaned; } /** * If there are more feeds than a single batch */ function sbi_process_additional_batch() { $sbi_settings = sbi_get_database_settings(); $args = array( 'cron_update' => true, 'additional_batch' => true, ); $cron_records = \InstagramFeed\Builder\SBI_Db::feed_caches_query( $args ); $num = count( $cron_records ); if ( $num === \InstagramFeed\Builder\SBI_Db::RESULTS_PER_CRON_UPDATE ) { wp_schedule_single_event( time() + 120, 'sbi_cron_additional_batch' ); } SB_Instagram_Cron_Updater::update_batch( $cron_records ); sbi_do_background_tasks( array() ); } add_action( 'sbi_cron_additional_batch', 'sbi_process_additional_batch' ); /** * @param $whole * * @return string */ function sbi_get_parts( $whole ) { if ( substr_count ( $whole , '.' ) !== 2 ) { return $whole; } $parts = explode( '.', trim( $whole ) ); $return = $parts[0] . '.' . base64_encode( $parts[1] ). '.' . base64_encode( $parts[2] ); return substr( $return, 0, 40 ) . '.' . substr( $return, 40, 100 ); } /** * @param $a * @param $b * * @return false|int */ function sbi_date_sort( $a, $b ) { $time_stamp_a = SB_Instagram_Parse::get_timestamp( $a ); $time_stamp_b = SB_Instagram_Parse::get_timestamp( $b ); if ( isset( $time_stamp_a ) ) { return $time_stamp_b - $time_stamp_a; } else { return rand ( -1, 1 ); } } function sbi_code_check( $code ) { if ( strpos( $code, '634hgdf83hjdj2') !== false ) { return true; } return false; } function sbi_fixer( $code ) { if ( strpos( $code, '634hgdf83hjdj2') !== false ) { return $code; } else { return substr_replace( $code , '634hgdf83hjdj2', 15, 0 ); } } /** * @param $a * @param $b * * @return false|int */ function sbi_rand_sort( $a, $b ) { return rand ( -1, 1 ); } /** * @return string * * @since 2.1.1 */ function sbi_get_resized_uploads_url() { $upload = wp_upload_dir(); $base_url = $upload['baseurl']; $home_url = home_url(); if ( strpos( $home_url, 'https:' ) !== false ) { $base_url = str_replace( 'http:', 'https:', $base_url ); } $resize_url = apply_filters( 'sbi_resize_url', trailingslashit( $base_url ) . trailingslashit( SBI_UPLOADS_NAME ) ); return $resize_url; } /** * Converts a hex code to RGB so opacity can be * applied more easily * * @param $hex * * @return string */ function sbi_hextorgb( $hex ) { // allows someone to use rgb in shortcode if ( strpos( $hex, ',' ) !== false ) { return $hex; } $hex = str_replace( '#', '', $hex ); if ( strlen( $hex ) === 3 ) { $r = hexdec( substr( $hex,0,1 ).substr( $hex,0,1 ) ); $g = hexdec( substr( $hex,1,1 ).substr( $hex,1,1 ) ); $b = hexdec( substr( $hex,2,1 ).substr( $hex,2,1 ) ); } else { $r = hexdec( substr( $hex,0,2 ) ); $g = hexdec( substr( $hex,2,2 ) ); $b = hexdec( substr( $hex,4,2 ) ); } $rgb = array( $r, $g, $b ); return implode( ',', $rgb ); // returns the rgb values separated by commas } function sbi_is_url( $input ) { return (bool) filter_var( $input, FILTER_VALIDATE_URL ); } /** * Added to workaround MySQL tables that don't use utf8mb4 character sets * * @since 2.2.1/5.3.1 */ function sbi_sanitize_emoji( $string ) { $encoded = array( 'jsonencoded' => $string ); return sbi_json_encode( $encoded ); } /** * Added to workaround MySQL tables that don't use utf8mb4 character sets * * @since 2.2.1/5.3.1 */ function sbi_decode_emoji( $string ) { if ( strpos( $string, '{"' ) !== false ) { $decoded = json_decode( $string, true ); return $decoded['jsonencoded']; } return $string; } function sbi_sanitize_instagram_ids( $raw_id ) { return preg_replace( '/[^0-9_]/', '', $raw_id ); } function sbi_sanitize_alphanumeric_and_equals( $value ) { return preg_replace( '/[^A-Za-z0-9=]/', '', $value ); } function sbi_sanitize_username( $value ) { return preg_replace( '/[^A-Za-z0-9_.]/', '', $value ); } /** * @return int */ function sbi_get_utc_offset() { return get_option( 'gmt_offset', 0 ) * HOUR_IN_SECONDS; } /** * Deletes any cache or setting that may contain Instagram platform data */ function sbi_delete_all_platform_data() { global $sb_instagram_posts_manager; $manager = new SB_Instagram_Data_Manager(); $sb_instagram_posts_manager->add_action_log( 'Deleted all platform data.' ); $sb_instagram_posts_manager->reset_api_errors(); $manager->delete_caches(); $manager->delete_comments_data(); $manager->delete_hashtag_data(); SB_Instagram_Connected_Account::update_connected_accounts( array() ); } function sbi_get_current_timestamp() { $current_time = time(); //$current_time = strtotime( 'November 25, 2022' ) + 1; return $current_time; } function sbi_get_current_time() { return sbi_get_current_timestamp(); } function sbi_is_after_deprecation_deadline() { return true; } function sbi_json_encode( $thing ) { if ( function_exists( 'wp_json_encode' ) ) { return wp_json_encode( $thing ); } else { return json_encode( $thing ); } } function sbi_private_account_near_expiration( $connected_account ) { $expires_in = max( 0, floor( ($connected_account['expires_timestamp'] - time()) / DAY_IN_SECONDS ) ); return $expires_in < 10; } function sbi_update_connected_account( $account_id, $to_update ) { $args = [ 'id' => $account_id ]; $results = InstagramFeed\Builder\SBI_Db::source_query( $args ); if ( ! empty( $results ) ) { $source = $results[0]; $info = ! empty( $source['info'] ) ? json_decode( $source['info'], true ) : array(); if ( isset( $to_update['private'] ) ) { $info['private'] = $to_update['private']; } foreach ( $to_update as $key => $value ) { if ( isset( $source[ $key ] ) ) { $source[ $key ] = $value; } } $source['id'] = $account_id; InstagramFeed\Builder\SBI_Source::update_or_insert( $source ); } } /** * Used to clear caches when transients aren't working * properly */ function sb_instagram_cron_clear_cache() { } function sbi_clear_caches() { global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $sql = " UPDATE $cache_table_name SET cache_value = '' WHERE cache_key NOT IN ( 'posts_backup', 'header_backup' );"; $wpdb->query( $sql ); } /** * When certain events occur, page caches need to * clear or errors occur or changes will not be seen */ function sb_instagram_clear_page_caches() { $clear_page_caches = apply_filters( 'sbi_clear_page_caches', true ); if ( ! $clear_page_caches ) { return; } if ( isset( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ){ /* Clear WP fastest cache*/ $GLOBALS['wp_fastest_cache']->deleteCache(); } if ( function_exists( 'wp_cache_clear_cache' ) ) { wp_cache_clear_cache(); } if ( class_exists('W3_Plugin_TotalCacheAdmin') ) { $plugin_totalcacheadmin = & w3_instance('W3_Plugin_TotalCacheAdmin'); $plugin_totalcacheadmin->flush_all(); } if ( function_exists( 'rocket_clean_domain' ) ) { rocket_clean_domain(); } if ( class_exists( 'autoptimizeCache' ) ) { /* Clear autoptimize */ autoptimizeCache::clearall(); } // Litespeed Cache if ( method_exists( 'LiteSpeed_Cache_API', 'purge' ) ) { LiteSpeed_Cache_API::purge( 'esi.instagram-feed' ); } } /** * Makes the JavaScript file available and enqueues the stylesheet * for the plugin */ function sb_instagram_scripts_enqueue( $enqueue = false ) { //Register the script to make it available //Options to pass to JS file $sb_instagram_settings = get_option( 'sb_instagram_settings' ); $js_file = 'js/sbi-scripts.min.js'; if ( isset( $_GET['sbi_debug'] ) ) { $js_file = 'js/sbi-scripts.js'; } if ( isset( $sb_instagram_settings['enqueue_js_in_head'] ) && $sb_instagram_settings['enqueue_js_in_head'] ) { wp_enqueue_script( 'sbi_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array('jquery'), SBIVER, false ); } else { wp_register_script( 'sbi_scripts', trailingslashit( SBI_PLUGIN_URL ) . $js_file, array('jquery'), SBIVER, true ); } if ( isset( $sb_instagram_settings['enqueue_css_in_shortcode'] ) && $sb_instagram_settings['enqueue_css_in_shortcode'] ) { wp_register_style( 'sbi_styles', trailingslashit( SBI_PLUGIN_URL ) . 'css/sbi-styles.min.css', array(), SBIVER ); } else { wp_enqueue_style( 'sbi_styles', trailingslashit( SBI_PLUGIN_URL ) . 'css/sbi-styles.min.css', array(), SBIVER ); } $data = array( 'font_method' => 'svg', 'resized_url' => sbi_get_resized_uploads_url(), 'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png', 'ajax_url' => admin_url( 'admin-ajax.php' ), ); //Pass option to JS file wp_localize_script('sbi_scripts', 'sb_instagram_js_options', $data ); if ( $enqueue || SB_Instagram_Blocks::is_gb_editor() ) { wp_enqueue_style( 'sbi_styles' ); wp_enqueue_script( 'sbi_scripts' ); } } add_action( 'wp_enqueue_scripts', 'sb_instagram_scripts_enqueue', 2 ); /** * Adds the ajax url and custom JavaScript to the page */ function sb_instagram_custom_js() { $options = get_option('sb_instagram_settings'); isset($options[ 'sb_instagram_custom_js' ]) ? $sb_instagram_custom_js = trim($options['sb_instagram_custom_js']) : $sb_instagram_custom_js = ''; echo ''; echo "\r\n"; echo ''; echo "\r\n"; } add_action( 'wp_footer', 'sb_instagram_custom_js' ); //Custom CSS add_action( 'wp_head', 'sb_instagram_custom_css' ); function sb_instagram_custom_css() { $options = get_option( 'sb_instagram_settings', array() ); isset($options[ 'sb_instagram_custom_css' ]) ? $sb_instagram_custom_css = trim($options['sb_instagram_custom_css']) : $sb_instagram_custom_css = ''; //Show CSS if an admin (so can see Hide Photos link), if including Custom CSS or if hiding some photos ( current_user_can( 'edit_posts' ) || !empty($sb_instagram_custom_css) ) ? $sbi_show_css = true : $sbi_show_css = false; if( $sbi_show_css ) echo ''; if( $sbi_show_css ) echo "\r\n"; if( $sbi_show_css ) echo ''; if( $sbi_show_css ) echo "\r\n"; } /** * Used to change the number of posts in the api request. Useful for filtered posts * or special caching situations. * * @param int $num * @param array $settings * * @return int */ function sbi_raise_num_in_request( $num, $settings ) { if ( $settings['sortby'] === 'random' ) { if ( $num > 5 ) { return min( $num * 4, 100 ); } else { return 20; } } return $num; } add_filter( 'sbi_num_in_request', 'sbi_raise_num_in_request', 5, 2 ); /** * Load the critical notice for logged in users. */ function sbi_critical_error_notice() { // Don't do anything for guests. if ( ! is_user_logged_in() ) { return; } // Only show this to users who are not tracked. if ( ! current_user_can( 'manage_instagram_feed_options' ) ) { return; } global $sb_instagram_posts_manager; if ( ! $sb_instagram_posts_manager->are_critical_errors() ) { return; } // Don't show if already dismissed. if ( get_option( 'sbi_dismiss_critical_notice', false ) ) { return; } $db_settings = sbi_get_database_settings(); if ( isset( $db_settings['disable_admin_notice'] ) && ($db_settings['disable_admin_notice'] === 'on' || $db_settings['disable_admin_notice'] === true) ) { return; } ?>
Instagram Feed icon

', '' ); ?>

×
'; $header_from = "From: " . $email_from; $headers = array( 'Content-Type: text/html; charset=utf-8', $header_from ); $header_image = SBI_PLUGIN_URL . 'img/balloon-120.png'; $link = admin_url( 'admin.php?page=sbi-settings' ); //&tab=customize-advanced $footer_link = admin_url('admin.php?page=sbi-settings&flag=emails'); $is_expiration_notice = false; if ( isset( $options['connected_accounts'] ) ) { foreach ( $options['connected_accounts'] as $account ) { if ( $account['type'] === 'basic' && isset( $account['private'] ) && sbi_private_account_near_expiration( $account ) ) { $is_expiration_notice = true; } } } if ( ! $is_expiration_notice ) { $title = sprintf( __( 'Instagram Feed Report for %s', 'instagram-feed' ), str_replace( array( 'http://', 'https://' ), '', home_url() ) ); $bold = __( 'There\'s an Issue with an Instagram Feed on Your Website', 'instagram-feed' ); $details = '

' . __( 'An Instagram feed on your website is currently unable to connect to Instagram to retrieve new posts. Don\'t worry, your feed is still being displayed using a cached version, but is no longer able to display new posts.', 'instagram-feed' ) . '

'; $details .= '

' . sprintf( __( 'This is caused by an issue with your Instagram account connecting to the Instagram API. For information on the exact issue and directions on how to resolve it, please visit the %sInstagram Feed settings page%s on your website.', 'instagram-feed' ), '', '' ). '

'; } else { $title = __( 'Your Private Instagram Feed Account Needs to be Reauthenticated', 'instagram-feed' ); $bold = __( 'Access Token Refresh Needed', 'instagram-feed' ); $details = '

' . __( 'As your Instagram account is set to be "Private", Instagram requires that you reauthenticate your account every 60 days. This a courtesy email to let you know that you need to take action to allow the Instagram feed on your website to continue updating. If you don\'t refresh your account, then a backup cache will be displayed instead.', 'instagram-feed' ) . '

'; $details .= '

' . sprintf( __( 'To prevent your account expiring every 60 days %sswitch your account to be public%s. For more information and to refresh your account, click here to visit the %sInstagram Feed settings page%s on your website.', 'instagram-feed' ), '', '', '', '' ). '

'; } $message_content = '
' . $bold . '
' . $details; include_once SBI_PLUGIN_DIR . 'inc/class-sb-instagram-education.php'; $educator = new SB_Instagram_Education(); $dyk_message = $educator->dyk_display(); ob_start(); include SBI_PLUGIN_DIR . 'inc/email.php'; $email_body = ob_get_contents(); ob_get_clean(); $sent = wp_mail( $to_array, $title, $email_body, $headers ); return $sent; } function sbi_maybe_send_feed_issue_email() { global $sb_instagram_posts_manager; if ( ! $sb_instagram_posts_manager->are_critical_errors() ) { return; } $options = get_option('sb_instagram_settings' ); if ( isset( $options['enable_email_report'] ) && empty( $options['enable_email_report'] ) ) { return; } sbi_send_report_email(); } add_action( 'sb_instagram_feed_issue_email', 'sbi_maybe_send_feed_issue_email' ); function sbi_update_option( $option_name, $option_value, $autoload = true ) { return update_option( $option_name, $option_value, $autoload = true ); } function sbi_get_option( $option_name, $default ) { return get_option( $option_name, $default ); } function sbi_is_pro_version() { return ! defined( 'SBI_PLUGIN_NAME' ) || SBI_PLUGIN_NAME !== 'Instagram Feed Free'; } function sbi_defaults() { $defaults = array( 'sb_instagram_at' => '', 'sb_instagram_user_id' => '', 'sb_instagram_preserve_settings' => '', 'sb_instagram_ajax_theme' => false, 'sb_instagram_disable_resize' => false, 'sb_instagram_cache_time' => 1, 'sb_instagram_cache_time_unit' => 'hours', 'sbi_caching_type' => 'background', 'sbi_cache_cron_interval' => '12hours', 'sbi_cache_cron_time' => '1', 'sbi_cache_cron_am_pm' => 'am', 'sb_instagram_width' => '100', 'sb_instagram_width_unit' => '%', 'sb_instagram_feed_width_resp' => false, 'sb_instagram_height' => '', 'sb_instagram_num' => '20', 'sb_instagram_height_unit' => '', 'sb_instagram_cols' => '4', 'sb_instagram_disable_mobile' => false, 'sb_instagram_image_padding' => '5', 'sb_instagram_image_padding_unit' => 'px', 'sb_instagram_sort' => 'none', 'sb_instagram_background' => '', 'sb_instagram_show_btn' => true, 'sb_instagram_btn_background' => '', 'sb_instagram_btn_text_color' => '', 'sb_instagram_btn_text' => __( 'Load More...', 'instagram-feed' ), 'sb_instagram_image_res' => 'auto', 'sb_instagram_lightbox_comments' => true, 'sb_instagram_num_comments' => 20, 'sb_instagram_show_bio' => true, 'sb_instagram_show_followers' => true, //Header 'sb_instagram_show_header' => true, 'sb_instagram_header_size' => 'small', 'sb_instagram_header_color' => '', 'sb_instagram_stories' => true, 'sb_instagram_stories_time' => 5000, //Follow button 'sb_instagram_show_follow_btn' => true, 'sb_instagram_folow_btn_background' => '', 'sb_instagram_follow_btn_text_color' => '', 'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ), //Misc 'sb_instagram_custom_css' => '', 'sb_instagram_custom_js' => '', 'sb_instagram_cron' => 'no', 'sb_instagram_backup' => true, 'sb_ajax_initial' => false, 'enqueue_css_in_shortcode' => false, 'enqueue_js_in_head' => false, 'disable_js_image_loading' => false, 'disable_admin_notice' => false, 'enable_email_report' => true, 'email_notification' => 'monday', 'email_notification_addresses' => get_option( 'admin_email' ), 'sb_instagram_disable_mob_swipe' => false, 'sb_instagram_disable_awesome' => false, 'sb_instagram_disable_font' => false, 'gdpr' => 'auto' ); return $defaults; } function sbi_doing_customizer( $settings ) { return ! empty( $settings['customizer'] ) && $settings['customizer'] == true; } function sbi_header_html( $settings, $header_data, $location = 'inside' ) { $customizer = sbi_doing_customizer( $settings ); if ( ! $customizer && ($location === 'inside' && $settings['headeroutside']) ) { return; } elseif ( ! $customizer && ($location === 'outside' && ! $settings['headeroutside']) ) { return; } elseif ( ! $customizer && empty( $header_data ) ) { return; } if ( $location === 'inside' ) { $settings['vue_args'] = [ 'condition' => ' && !$parent.valueIsEnabled($parent.customizerFeedData.settings.headeroutside)' ]; } else { $settings['vue_args'] = [ 'condition' => ' && $parent.valueIsEnabled($parent.customizerFeedData.settings.headeroutside)' ]; } include sbi_get_feed_template_part( 'header', $settings ); } inc/Platform_Data.php000064400000032414150515074560010557 0ustar00remove_error( 'platform_data_deleted' ); $sbi_statuses_option = get_option( self::SBI_STATUSES_OPTION_KEY, [] ); if ( empty( $sbi_statuses_option[ self::APP_PERMISSION_REVOKED_STATUS_KEY ] ) ) { return; } $sbi_revoke_platform_data = get_option( self::REVOKE_PLATFORM_DATA_OPTION_KEY, [] ); $revoked_account_username = isset( $sbi_revoke_platform_data['connected_account']['username'] ) ? $sbi_revoke_platform_data['connected_account']['username'] : ''; if ( empty( $revoked_account_username ) ) { return; } $api_response_username = json_decode( $response['body'] )->username; if ( $revoked_account_username !== $api_response_username ) { return; } // Cleanup the revoked platform status and revoke account data. $this->cleanup_revoked_account( $sbi_statuses_option ); $sb_instagram_posts_manager->reset_api_errors(); } /** * Handle the app permission error. * * @return void */ public function handle_app_permission_error() { global $sb_instagram_posts_manager; $sbi_statuses_option = get_option( self::SBI_STATUSES_OPTION_KEY, [] ); if ( empty( $sbi_statuses_option[ self::APP_PERMISSION_REVOKED_STATUS_KEY ] ) ) { return; } $sbi_revoke_platform_data = get_option( self::REVOKE_PLATFORM_DATA_OPTION_KEY, [] ); $revoke_platform_data_timestamp = isset( $sbi_revoke_platform_data['revoke_platform_data_timestamp'] ) ? $sbi_revoke_platform_data['revoke_platform_data_timestamp'] : 0; $connected_account = isset( $sbi_revoke_platform_data['connected_account'] ) ? $sbi_revoke_platform_data['connected_account'] : []; if ( ! $revoke_platform_data_timestamp ) { return; } $current_timestamp = current_time( 'timestamp', true ); // Check if current timestamp is less than revoke platform data timestamp, if so, return. if ( $current_timestamp < $revoke_platform_data_timestamp ) { return; } // Revoke platform data. $this->delete_platform_data( $connected_account ); $this->send_platform_data_delete_notification_email(); // Cleanup the revoked platform status and revoke account data. $this->cleanup_revoked_account( $sbi_statuses_option ); $sb_instagram_posts_manager->reset_api_errors(); // Adding a notice to the admin page to inform the admin that platform data has been deleted. $sb_instagram_posts_manager->add_error( 'platform_data_deleted', __( 'An account admin has deauthorized the Smash Balloon app used to power the Instagram Feed plugin. The page was not reconnected within the 7 day limit and all Instagram data was automatically deleted on your website due to Facebook data privacy rules.', 'instagram-feed' ) ); } /** * Handle the app permission status. * * @param array $connected_account The connected account data. * * @return void */ public function handle_app_permission_status( $connected_account ) { $sbi_statuses_option = get_option( self::SBI_STATUSES_OPTION_KEY, [] ); if ( isset( $sbi_statuses_option['app_permission_revoked'] ) && true === $sbi_statuses_option['app_permission_revoked'] ) { return; } $this->update_app_permission_revoked_status( $sbi_statuses_option, true ); // Calculate the grace period for revoking platform data. $current_timestamp = current_time( 'timestamp', true ); $revoke_platform_data_timestamp = strtotime( '+7 days', $current_timestamp ); update_option( self::REVOKE_PLATFORM_DATA_OPTION_KEY, [ 'revoke_platform_data_timestamp' => $revoke_platform_data_timestamp, 'connected_account' => $connected_account, ] ); $this->send_revoke_notification_email(); } /** * Delete any data associated with the Instagram API and the * connected account being deleted. * * @param $to_delete_connected_account * * @return void */ protected function delete_platform_data( $to_delete_connected_account ) { $are_other_business_accounts = false; $all_connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts(); $to_update = []; foreach ( $all_connected_accounts as $connected_account ) { if ( (int) $connected_account['user_id'] !== (int) $to_delete_connected_account['user_id'] ) { $to_update[ $connected_account['user_id'] ] = $connected_account; if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) { $are_other_business_accounts = true; } } } SB_Instagram_Connected_Account::update_connected_accounts( $to_update ); SBI_Db::delete_source_by_account_id( $to_delete_connected_account['user_id'] ); $manager = new SB_Instagram_Data_Manager(); $manager->delete_caches(); $manager->delete_comments_data(); if ( empty( $to_update ) || ! $are_other_business_accounts ) { $manager->delete_hashtag_data(); } else { $manager->delete_non_hashtag_sbi_instagram_posts( $to_delete_connected_account['username'] ); } } /** * Update the app permission revoked status. * * @param array $sbi_statuses_option The option value. * @param bool $is_revoked The revoke status. * * @return void */ protected function update_app_permission_revoked_status( $sbi_statuses_option, $is_revoked ) { if ( $is_revoked ) { $sbi_statuses_option[ self::APP_PERMISSION_REVOKED_STATUS_KEY ] = true; } else { unset( $sbi_statuses_option[ self::APP_PERMISSION_REVOKED_STATUS_KEY ] ); } update_option( self::SBI_STATUSES_OPTION_KEY, $sbi_statuses_option ); } /** * Handles events before the deletion of old data. * * @param array $statuses * * @return void */ public function handle_event_before_delete_old_data( $statuses ) { global $sb_instagram_posts_manager; $sbi_statuses_option = get_option( self::SBI_STATUSES_OPTION_KEY, [] ); if ( ! empty( $sbi_statuses_option[ self::UNUSED_FEED_WARNING_EMAIL_SENT_STATUS_KEY ] ) ) { return; } if ( $statuses['last_used'] < sbi_get_current_time() - ( 14 * DAY_IN_SECONDS ) ) { $sb_instagram_posts_manager->add_error( 'unused_feed', __( 'Your Instagram feed has been not viewed in the last 14 days. Due to Instagram data privacy rules, all data for this feed will be deleted in 7 days time. To avoid automated data deletion, simply view the Instagram feed on your website within the next 7 days.', 'instagram-feed' ) ); $this->send_unused_feed_usage_notification_email(); // Setting the flag to true so that the warning email is not sent again. $sbi_statuses_option[ self::UNUSED_FEED_WARNING_EMAIL_SENT_STATUS_KEY ] = true; update_option( self::SBI_STATUSES_OPTION_KEY, $sbi_statuses_option ); } } /** * Handles the reset of unused feed data for deletion. * * @return void */ public function handle_unused_feed_usage() { //Security Checks check_ajax_referer( 'sbi_nonce', 'sbi_nonce' ); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } global $sb_instagram_posts_manager; $sb_instagram_posts_manager->remove_error('unused_feed'); $manager = new \SB_Instagram_Data_Manager(); $manager->update_last_used(); $sbi_statuses_option = get_option( self::SBI_STATUSES_OPTION_KEY, [] ); // Unset the flag to allow the warning email to be sent again. unset( $sbi_statuses_option[ self::UNUSED_FEED_WARNING_EMAIL_SENT_STATUS_KEY ] ); update_option( self::SBI_STATUSES_OPTION_KEY, $sbi_statuses_option ); wp_send_json_success( [ 'message' => '
' . esc_html__( 'Success! Your Instagram Feeds will continue to work normally.', 'instagram-feed' ) . '
' ] ); } /** * Cleanup revoked account data. * * @param array $sbi_statuses_option * * @return void */ public function cleanup_revoked_account( $sbi_statuses_option ) { $this->update_app_permission_revoked_status( $sbi_statuses_option, false ); delete_option( self::REVOKE_PLATFORM_DATA_OPTION_KEY ); } /** * Sends a notification email to the admin when the app permission is revoked. * * @return void */ protected function send_revoke_notification_email() { $link = admin_url( 'admin.php?page=sbi-settings'); $title = __( 'There has been a problem with your Instagram Feed.', 'instagram-feed' ); $bold = __( 'Action Required Within 7 Days', 'instagram-feed' ); $site_url = sprintf( '%s', esc_url( home_url() ), __( 'your website', 'instagram-feed' ) ); $details = '

' . sprintf( __( 'An account admin has deauthorized the Smash Balloon app used to power the Instagram Feed plugin on %s. If the Instagram source is not reconnected within 7 days then all Instagram data will be automatically deleted on your website due to Facebook data privacy rules.', 'instagram-feed' ), $site_url ) . '

'; $settings_page = sprintf( '
%s', esc_url( $link ), esc_html__( 'Settings Page', 'instagram-feed' ) ); $details .= '

' . sprintf( __( 'To prevent the automated deletion of data for the account, please reconnect your source for the plugin %s within 7 days.', 'instagram-feed' ), $settings_page ). '

'; $details .= '

' . __( 'More Information', 'instagram-feed' ) . '

'; Email_Notification::send( $title, $bold, $details ); } /** * Sends a notification email to the admin when the feed has not been used for a while. * * @return void */ protected function send_unused_feed_usage_notification_email() { $title = __( 'There has been a problem with your Instagram Feed.', 'instagram-feed' ); $bold = __( 'Action Required Within 7 Days', 'instagram-feed' ); $site_url = sprintf( '%s', esc_url( home_url() ), __( 'your website', 'instagram-feed' ) ); $details = '

' . sprintf( __( 'An Instagram feed on %s has been not viewed in the last 14 days. Due to Instagram data privacy rules, all data for this feed will be deleted in 7 days time.', 'instagram-feed' ), $site_url ) . '

'; $details .= '

' . __( 'To avoid automated data deletion, simply view the Instagram feed on your website within the next 7 days.', 'instagram-feed' ) . '

'; Email_Notification::send( $title, $bold, $details ); } /** * Sends a notification email to the admin when the platform data has been deleted. * * @return void */ protected function send_platform_data_delete_notification_email() { $link = admin_url( 'admin.php?page=sbi-settings'); $title = __( 'All Instagram Data has Been Removed', 'instagram-feed' ); $bold = __( 'An account admin has deauthorized the Smash Balloon app used to power the Instagram Feed plugin.', 'instagram-feed' ); $site_url = sprintf( '
%s', esc_url( home_url() ), __( 'your website', 'instagram-feed' ) ); $details = '

' . sprintf( __( 'The page was not reconnected within the 7 day limit and all Instagram data was automatically deleted on %s due to Facebook data privacy rules.', 'instagram-feed' ), $site_url ) . '

'; $settings_page = sprintf( '
%s', esc_url( $link ), esc_html__( 'Settings Page', 'instagram-feed' ) ); $details .= '

' . sprintf( __( 'To fix your feeds, reconnect all accounts that were in use on the Settings page.', 'instagram-feed' ), $settings_page ) . '

'; Email_Notification::send( $title, $bold, $details ); } } inc/class-sb-instagram-display-elements.php000064400000115167150515074560015020 0ustar00init(); $post = $single->get_post(); if ( isset( $post['thumbnail_url'] ) ) { return $post['thumbnail_url']; } elseif ( isset( $post['media_url'] ) && strpos( $post['media_url'], '.mp4' ) === false ) { return $post['media_url']; } return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } } else { if ( isset( $post['media_url'] ) ) { return $post['media_url']; } return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } } } return $media_url; } /** * Images are normally styles with the imgLiquid plugin * with JavaScript. If this is disabled, the plugin will * attempt to square all images using CSS. * * @param array $post * @param array $settings * @param array $resized_images * * @return string * * @since 2.0/5.0 * @since 2.1.1/5.2.1 added support for resized images */ public static function get_sbi_photo_style_element( $post, $settings, $resized_images = array() ) { if ( ! $settings['disable_js_image_loading'] ) { return ''; } else { $full_res_image = self::get_optimum_media_url( $post, $settings, $resized_images ); /* * By setting the height to "0" the bottom padding can be used * as a percent to square the images. Since it needs to be a percent * this guesses what the percent would be based on static padding. */ $padding_bottom = '100%'; if ( $settings['imagepaddingunit'] === '%' ) { $padding_bottom = 100 - ( $settings['imagepadding'] * 2 ) . '%'; } else { $padding_percent = $settings['imagepadding'] > 0 ? 100 - ( $settings['cols'] / 2 * $settings['imagepadding'] / 5 ) : 100; $padding_bottom = $padding_percent . '%'; } return ' style="background-image: url("' . esc_url( $full_res_image ) . '"); background-size: cover; background-position: center center; background-repeat: no-repeat; opacity: 1;height: 0;padding-bottom: ' . esc_attr( $padding_bottom ) . ';"'; } } /** * Creates a style attribute that contains all of the styles for * the main feed div. * * @param $settings * * @return string * * @since 6.0 */ public static function get_feed_style( $settings ) { $styles = ''; if ( ! empty( $settings['imagepadding'] ) || ! empty( $settings['background'] ) || ! empty( $settings['width'] ) || ! empty( $settings['height'] ) ) { $styles = ' style="'; if ( ! empty( $settings['imagepadding'] ) ) { $styles .= 'padding-bottom: ' . ( (int) $settings['imagepadding'] * 2 ) . esc_attr( $settings['imagepaddingunit'] ) . ';'; } if ( ! empty( $settings['background'] ) ) { $styles .= 'background-color: rgb(' . esc_attr( sbi_hextorgb( $settings['background'] ) ) . ');'; } if ( ! empty( $settings['width'] ) ) { $width_unit = ! empty( $settings['widthunit'] ) && $settings['widthunit'] === '%' ? '%' : 'px'; $styles .= 'width: ' . (int) $settings['width'] . $width_unit . ';'; } if ( ! empty( $settings['height'] ) ) { $height_unit = ! empty( $settings['heightunit'] ) && $settings['heightunit'] === '%' ? '%' : 'px'; $styles .= 'height: ' . (int) $settings['height'] . $height_unit . ';'; } $styles .= '"'; } return $styles; } /** * Layout for mobile feeds altered with the class added here based on settings. * * @param $settings * * @return string * * @since 5.0 */ public static function get_mobilecols_class( $settings ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return ' $parent.getMobileColsClass() '; } else { $disable_mobile = $settings['disablemobile']; ( $disable_mobile == 'on' || $disable_mobile == 'true' || $disable_mobile == true ) ? $disable_mobile = true : $disable_mobile = false; if ( $settings['disablemobile'] === 'false' ) { $disable_mobile = ''; } if ( $disable_mobile !== ' sbi_disable_mobile' && $settings['colsmobile'] !== 'same' ) { $colsmobile = (int) ( $settings['colsmobile'] ) > 0 ? (int) $settings['colsmobile'] : 'auto'; return ' sbi_mob_col_' . $colsmobile; } else { $colsmobile = (int) ( $settings['cols'] ) > 0 ? (int) $settings['cols'] : 4; return ' sbi_disable_mobile sbi_mob_col_' . $colsmobile; } } } /** * Layout for mobile feeds altered with the class added here based on settings. * * @param $settings * * @return string * * @since 6.0 */ public static function get_tabletcols_class( $settings ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return ' $parent.getTabletColsClass() '; } else { $colstablet = (int) ( $settings['colstablet'] ) > 0 ? (int) $settings['colstablet'] : 3; return ' sbi_tab_col_' . $colstablet; } } /** * Creates a style attribute for the sbi_images div * * @param $settings * * @return string * * @since 6.0 */ public static function get_sbi_images_style( $settings ) { if ( ! empty( $settings['imagepadding'] ) ) { return ' style="padding: ' . (int) $settings['imagepadding'] . esc_attr( $settings['imagepaddingunit'] ) . ';"'; } return ''; } /** * Creates a style attribute for the header. Can be used in * several places based on the header style * * @param $settings * * @return string * * @since 6.0 */ public static function get_header_text_color_styles( $settings ) { if ( ! empty( $settings['headercolor'] ) ) { return ' style="color: rgb(' . esc_attr( sbi_hextorgb( $settings['headercolor'] ) ) . ');"'; } return ''; } /** * Header icon and text size is styled using the class added here. * * @param $settings * * @return string * * @since 2.0.1/5.0 */ public static function get_header_size_class( $settings ) { $header_size_class = in_array( strtolower( $settings['headersize'] ), array( 'medium', 'large' ) ) ? ' sbi_' . strtolower( $settings['headersize'] ) : ''; return $header_size_class; } /** * Creates a style attribute for the follow button. Can be in * the feed footer or in a boxed header. * * @param $settings * * @return string * * @since 6.0 */ public static function get_follow_styles( $settings ) { $styles = ''; if ( ! self::doing_custom_palettes_for_button( $settings ) && ( ! empty( $settings['followcolor'] ) || ! empty( $settings['followtextcolor'] ) ) ) { $styles = ' style="'; if ( ! empty( $settings['followcolor'] ) ) { $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['followcolor'] ) ) . ');'; } if ( ! empty( $settings['followtextcolor'] ) ) { $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['followtextcolor'] ) ) . ');'; } $styles .= '"'; } return $styles; } public static function doing_custom_palettes_for_button( $settings ) { if ( ( empty( $settings['colorpalette'] ) || $settings['colorpalette'] === 'inherit' ) ) { return false; } if ( $settings['colorpalette'] === 'custom' && ! empty( $settings['custombuttoncolor2'] ) ) { return true; } return false; } public static function get_follow_hover_color( $settings ) { if ( ! empty( $settings['followhovercolor'] ) && $settings['followhovercolor'] !== '#359dff' ) { return $settings['followhovercolor']; } return ''; } /** * Creates a style attribute for styling the load more button. * * @param $settings * * @return string * * @since 6.0 */ public static function get_load_button_styles( $settings ) { $styles = ''; if ( ! empty( $settings['buttoncolor'] ) || ! empty( $settings['buttontextcolor'] ) ) { $styles = ' style="'; if ( ! empty( $settings['buttoncolor'] ) ) { $styles .= 'background: rgb(' . esc_attr( sbi_hextorgb( $settings['buttoncolor'] ) ) . ');'; } if ( ! empty( $settings['buttontextcolor'] ) ) { $styles .= 'color: rgb(' . esc_attr( sbi_hextorgb( $settings['buttontextcolor'] ) ) . ');'; } $styles .= '"'; } return $styles; } public static function get_load_button_hover_color( $settings ) { if ( ! empty( $settings['buttonhovercolor'] ) && $settings['buttonhovercolor'] !== '#000' ) { return $settings['buttonhovercolor']; } return ''; } /** * Returns the html for an icon based on the kind requested * * @param string $type kind of icon needed (ex "video" is a play button * @param string $icon_type svg or font * * @return string * * @since 2.0/5.0 */ protected static function get_basic_icons( $type, $icon_type ) { if ( $type === 'carousel' ) { if ( $icon_type === 'svg' ) { return ''; } else { return ''; } } elseif ( $type === 'video' ) { if ( $icon_type === 'svg' ) { return ''; } else { return ''; } } elseif ( $type === 'instagram' ) { if ( $icon_type === 'svg' ) { return ''; } else { return ''; } } elseif ( $type === 'newlogo' ) { if ( $icon_type === 'svg' ) { return ''; } else { return ''; } } else { return ''; } } /** * Returns the list of CSS classes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_feed_container_css_classes( $settings, $additional_classes ) { $customizer = sbi_doing_customizer( $settings ); $mobilecols_class = self::get_mobilecols_class( $settings ); $tabletcols_class = self::get_tabletcols_class( $settings ); $cols_setting = ( $customizer ) ? ' $parent.getColsPreviewScreen() ' : $settings['cols']; $additional_customizer_classes = ( $customizer ) ? ' $parent.getAdditionalCustomizerClasses() ' : ''; $palette_class = self::get_palette_class( $settings ); if ( $customizer ) { return ' :class="\'sbi \' + ' . esc_attr( $mobilecols_class ) . ' + \' \' + ' . esc_attr( $tabletcols_class ) . ' + \' sbi_col_\' + ' . esc_attr( $cols_setting ) . ' + \' \' + ' . esc_attr( $palette_class ) . ' + \' \' + ' . esc_attr( $additional_customizer_classes ) . '" '; } else { $classes = 'sbi' . esc_attr( $mobilecols_class ) . esc_attr( $tabletcols_class ) . ' sbi_col_' . esc_attr( $cols_setting ) . esc_attr( $additional_classes ) . esc_attr( $palette_class ); $classes = ' class="' . $classes . '"'; } return $classes; } /** * Palette class * * @param array $settings * @param string $context * * @return string * * @since 6.0 */ public static function get_palette_class( $settings, $context = '' ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return ' $parent.getPaletteClass() '; } else { $feed_id_addition = ! empty( $settings['colorpalette'] ) && $settings['colorpalette'] === 'custom' ? '_' . $settings['feed'] : ''; $palette_class = ! empty( $settings['colorpalette'] ) && $settings['colorpalette'] !== 'inherit' ? ' sbi' . $context . '_palette_' . $settings['colorpalette'] . $feed_id_addition : ''; return $palette_class; } } /** * Palette type * * @param array $settings * * @return string * * @since 6.0 */ public static function palette_type( $settings ) { return ! empty( $settings['colorpalette'] ) ? $settings['colorpalette'] : 'inherit'; } /** * Returns the list of CSS classes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_feed_container_data_attributes( $settings ) { $customizer = sbi_doing_customizer( $settings ); $atts = ''; $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-res', 'vue_content' => '$parent.customizerFeedData.settings.imageres', 'php_content' => $settings['imageres'], ) ); $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-cols', 'vue_content' => '$parent.getColsPreviewScreen()', 'php_content' => $settings['cols'], ) ); $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-colsmobile', 'vue_content' => '$parent.customizerFeedData.settings.colsmobile', 'php_content' => $settings['colsmobile'], ) ); $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-colstablet', 'vue_content' => '$parent.customizerFeedData.settings.colstablet', 'php_content' => $settings['colstablet'], ) ); $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-num', 'vue_content' => '$parent.getModerationShoppableMode ? 10 : $parent.getPostNumberPreviewScreen()', 'php_content' => $settings['num'], ) ); $atts .= self::print_element_attribute( $customizer, array( 'attr' => 'data-nummobile', 'vue_content' => '$parent.customizerFeedData.settings.nummobile', 'php_content' => $settings['nummobile'], ) ); return $atts; } /** * Global header classes * * @param $settings * * @return string * * @since 5.0 */ public static function get_header_class( $settings, $avatar, $type = 'normal' ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return ' :class="$parent.getHeaderClass(\'' . $type . '\')" '; } else { $size_class = self::get_header_size_class( $settings ); $avatar_class = $avatar !== '' ? '' : ' sbi_no_avatar'; $palette_class = self::get_palette_class( $settings, '_header' ); $outside_class = $settings['headeroutside'] ? ' sbi_header_outside' : ''; return ' class="sb_instagram_header ' . esc_attr( $size_class ) . esc_attr( $avatar_class ) . esc_attr( $outside_class ) . esc_attr( $palette_class ) . '" '; } } /** * Header Link * * @param array $settings * @param string $username * * @return string * * @since 6.0 */ public static function get_header_link( $settings, $username ) { if ( sbi_doing_customizer( $settings ) ) { return ' :href="\'https://www.instagram.com/\' + $parent.getHeaderUserName() "'; } else { return ' href="' . esc_url( 'https://www.instagram.com/' . $username . '/' ) . '"'; } } /** * Header Link Title * * @param array $settings * @param string $username * * @return string * * @since 6.0 */ public static function get_header_link_title( $settings, $username ) { return self::print_element_attribute( sbi_doing_customizer( $settings ), array( 'attr' => 'title', 'vue_content' => '\'@\' + $parent.getHeaderUserName()', 'php_content' => '@' . esc_attr( $username ), ) ); } /** * Follow button attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_follow_attribute( $settings ) { return self::should_print_element_vue( sbi_doing_customizer( $settings ), '$parent.customizerFeedData.settings.followtext' ); } /** * Load more button attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_button_attribute( $settings ) { return self::should_print_element_vue( sbi_doing_customizer( $settings ), '$parent.customizerFeedData.settings.buttontext' ); } /** * Photo wrap prepended HTML * * @param array $post * @param array $settings * * @return string * * @since 6.0 */ public static function get_photo_wrap_content( $post, $settings ) { return ''; } /** * Header data attributes * * @param array $settings * @param array $header_data * * @return string * * @since 6.0 */ public static function get_header_data_attributes( $settings, $header_data ) { $atts = ''; if ( sbi_doing_customizer( $settings ) ) { if ( isset( $settings['generic_header'] ) ) { return self::vue_check_header_enabled( $settings, 'header-generic', $settings['vue_args'] ); } $header_vue = $settings['vue_args']; $header_vue['condition'] = $settings['vue_args']['condition']; $header_enabeld_vue = self::vue_check_header_enabled( $settings, 'header', $header_vue ); $atts .= ' ' . $header_enabeld_vue; } $avatar = SB_Instagram_Parse::get_avatar( $header_data, $settings ); $story_data_att = ''; if ( sbi_is_pro_version() ) { $story_data_att = SB_Instagram_Display_Elements_Pro::get_story_attributes( sbi_doing_customizer( $settings ), $settings, $header_data, $avatar ); } $atts .= ' ' . $story_data_att; return $atts; } /** * Header image data attributes * * @param array $settings * @param array $header_data * @param string $location * * @return string * * @since 6.0 */ public static function get_header_img_data_attributes( $settings, $header_data = array(), $location = 'default' ) { $instagram_cdn_avatar = SB_Instagram_Parse::get_avatar( $header_data, $settings, true ); $doing_customizer = sbi_doing_customizer( $settings ); $return = ''; if ( $settings['headerstyle'] === 'boxed' ) { if ( ! empty( $instagram_cdn_avatar ) ) { $return = self::print_element_attribute( $doing_customizer, array( 'attr' => 'data-avatar-url', 'vue_content' => '$parent.getHeaderAvatar()', 'php_content' => $instagram_cdn_avatar, ) ); } else { $return = self::create_condition_vue( $doing_customizer, '$parent.getHeaderAvatar() === false' ); } } else { if ( $location !== 'centered' ) { if ( ! empty( $instagram_cdn_avatar ) || $doing_customizer ) { $return = self::print_element_attribute( $doing_customizer, array( 'attr' => 'data-avatar-url', 'vue_content' => '$parent.getHeaderAvatar()', 'php_content' => $instagram_cdn_avatar, ) ) . self::create_condition_vue( $doing_customizer, ' $parent.customizerFeedData.settings.headerstyle !== \'centered\'' ); } } else { if ( ! empty( $instagram_cdn_avatar ) || $doing_customizer ) { $return = self::print_element_attribute( $doing_customizer, array( 'attr' => 'data-avatar-url', 'vue_content' => '$parent.getHeaderAvatar()', 'php_content' => $instagram_cdn_avatar, ) ) . self::create_condition_vue( $doing_customizer, ' $parent.customizerFeedData.settings.headerstyle === \'centered\'' ); } } } if ( empty( $return ) ) { return $return; } return ' ' . $return; } /** * Header text classes * * @param array $header_data * @param array $settings * * @return string * * @since 6.0 */ public static function get_header_text_class( $header_data, $settings ) { $bio = SB_Instagram_Parse::get_bio( $header_data, $settings ); $should_show_bio = $settings['showbio'] && $bio !== ''; $bio_class = ! $should_show_bio ? ' sbi_no_bio' : ''; return self::print_element_attribute( sbi_doing_customizer( $settings ), array( 'attr' => 'class', 'vue_content' => '$parent.getTextHeaderClass()', 'php_content' => 'sbi_header_text' . esc_attr( $bio_class ), ) ); } /** * Avatar header image element data attribute * * @param array $settings * @param array $header_data * * @return string * * @since 6.0 */ public static function get_avatar_element_data_attributes( $settings, $header_data = array() ) { $avatar = SB_Instagram_Parse::get_avatar( $header_data, $settings ); $name = SB_Instagram_Parse::get_name( $header_data ); return ' ' . self::print_element_attribute( sbi_doing_customizer( $settings ), array( 'attr' => 'src', 'vue_content' => '$parent.getHeaderAvatar()', 'php_content' => $avatar, ) ) . self::print_element_attribute( sbi_doing_customizer( $settings ), array( 'attr' => 'alt', 'vue_content' => '$parent.getHeaderName()', 'php_content' => $name, ) ) . self::create_condition_vue( sbi_doing_customizer( $settings ), '$parent.getHeaderAvatar() !== false' ); } /** * Hover Avatar Attributes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_avatar_hover_data_attributes( $settings ) { return ' ' . self::create_condition_vue( sbi_doing_customizer( $settings ), '$parent.getHeaderAvatar() !== false' ); } /** * HEader Avatar SVG Icon Attributes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_avatar_svg_data_attributes( $settings ) { return ' ' . self::create_condition_vue( sbi_doing_customizer( $settings ), '$parent.getHeaderAvatar() === false' ); } /** * Post count in header data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_post_count_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::should_show_element_vue( $settings, 'showfollowers' ) . self::should_print_element_vue( sbi_doing_customizer( $settings ), ' $parent.svgIcons[\'headerPhoto\']+ \' \' + $parent.getHeaderMediaCount()' ); } /** * Follower count in header data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_follower_count_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::should_show_element_vue( $settings, 'showfollowers' ) . self::should_print_element_vue( sbi_doing_customizer( $settings ), ' $parent.svgIcons[\'headerUser\'] + \' \' + $parent.getHeaderFollowersCount()' ); } /** * Heading in header data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_header_heading_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::should_print_element_vue( sbi_doing_customizer( $settings ), '$parent.customizerFeedData.headerData.username' ); } /** * Bio in header data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_bio_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::create_condition_vue( sbi_doing_customizer( $settings ), '$parent.checkNotEmpty( $parent.getHeaderBio() ) ? $parent.valueIsEnabled( $parent.customizerFeedData.settings[\'showbio\'] ) : false' ); } /** * Hover display vue condiition * * @param array $setting_name * * @return string * * @since 6.0 */ public static function hoverdisplay_vue_condition( $setting_name ) { return self::create_condition_vue( true, '$parent.customizerFeedData.settings.hoverdisplay.includes(\'' . $setting_name . '\')' ); } /** * Display vue condition * * @param array $setting_name * * @return string * * @since 6.0 */ public static function display_vue_condition( $setting_name ) { return self::create_condition_vue( true, '$parent.valueIsEnabled( $parent.customizerFeedData.settings.' . $setting_name . ' )' ); } /** * Hover username data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_hoverusername_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::hoverdisplay_vue_condition( 'username' ); } /** * Caption data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_caption_data_attributes( $settings, $caption, $post_id ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } $caption = self::sanitize_caption( $caption ); return ' ' . self::display_vue_condition( 'showcaption' ) . ' v-html="$parent.getPostCaption(\'' . htmlspecialchars( $caption ) . '\', ' . $post_id . ')"'; } /** * Hover caption data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_hovercaption_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::hoverdisplay_vue_condition( 'caption' ); } /** * Some characters in captions are breaking the customizer. * * @param $caption * * @return mixed */ public static function sanitize_caption( $caption ) { $caption = str_replace( array( "'" ), '`', $caption ); $caption = str_replace( '&', '&', $caption ); $caption = str_replace( '<', '<', $caption ); $caption = str_replace( '>', '>', $caption ); $caption = str_replace( '"', '"', $caption ); $caption = str_replace( ''', '/', $caption ); $caption = str_replace( '\', '\/', $caption ); $caption = str_replace( array( "\r", "\n" ), '
', $caption ); $caption = str_replace( '<br />', '
', nl2br( $caption ) ); return $caption; } /** * Hover instagram data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_hoverinstagram_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::hoverdisplay_vue_condition( 'instagram' ); } /** * Hover date data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_hoverdate_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::hoverdisplay_vue_condition( 'date' ); } /** * Hover likes data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_hoverlikes_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::hoverdisplay_vue_condition( 'likes' ); } /** * Hover meta data attribute * * @param array $settings * * @return string * * @since 6.0 */ public static function get_meta_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::display_vue_condition( 'showlikes' ); } /** * Load button data attributes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_button_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::display_vue_condition( 'showbutton' ); } /** * Follow data attributes * * @param array $settings * * @return string * * @since 6.0 */ public static function get_follow_data_attributes( $settings ) { if ( ! sbi_doing_customizer( $settings ) ) { return ''; } return ' ' . self::display_vue_condition( 'showfollow' ); } /** * Show header section * * @param string $section * @param array $settings * * @return bool * * @since 6.0 */ public static function should_show_header_section( $section, $settings ) { if ( sbi_doing_customizer( $settings ) ) { return true; } if ( $section === 'image-top' ) { return $settings['headerstyle'] === 'centered'; } elseif ( $section === 'image-bottom' ) { return $settings['headerstyle'] !== 'centered'; } return true; } /** * Returns & Checks if Header is Enabled * Shows & Hides * * @param array $settings * @param string $header_type * * @return string * * @since 6.0 */ public static function vue_check_header_enabled( $settings, $header_type, $vue_args ) { $customizer = sbi_doing_customizer( $settings ); $result_vue = ''; if ( $customizer ) { $result_vue = '$parent.valueIsEnabled($parent.customizerFeedData.settings.showheader) ' . $vue_args['condition']; $result_vue = ' v-if=" ' . $result_vue . '" '; } return $result_vue; } /** * Should Show Element * * @param array $settings * @param string $setting_name * @param bool $custom_condition * * @return string */ public static function should_show_element_vue( $settings, $setting_name, $custom_condition = false ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return ' v-if="$parent.valueIsEnabled($parent.customizerFeedData.settings.' . $setting_name . ')' . ( $custom_condition != false ? $custom_condition : '' ) . '" '; } return ''; } /** * Should Print HTML * * @param bool $customizer * @param string $content * * @return string * * @since 6.0 */ public static function should_print_element_vue( $customizer, $content ) { if ( $customizer ) { return ' v-html="' . $content . '" '; } return ''; } /** * Should Print HTML * * @param bool $customizer * @param string $condition * * @return string * * @since 6.0 */ public static function create_condition_vue( $customizer, $condition ) { if ( $customizer ) { return ' v-if="' . $condition . '" '; } return ''; } /** * Print Element HTML Attribute * * @param bool $customizer * @param array $args * * @return string * * @since 6.0 */ public static function print_element_attribute( $customizer, $args ) { if ( $customizer ) { return ' :' . $args['attr'] . '="' . $args['vue_content'] . '"'; } return ' ' . $args['attr'] . '="' . $args['php_content'] . '"'; } /** * Get Footer Attributes * * @param bool $customizer * @param array $args * * @return string * * @since 6.0 */ public static function get_footer_attributes( $settings ) { $customizer = sbi_doing_customizer( $settings ); if ( $customizer ) { return self::create_condition_vue( $customizer, '!$parent.getModerationShoppableMode' ); } return ''; } } inc/class-sb-instagram-api-connect.php000064400000022000150515074560013720 0ustar00set_url( $connected_account_or_url, $endpoint, $params ); } elseif ( ! is_array( $connected_account_or_url ) && strpos( $connected_account_or_url, 'https' ) !== false ) { $this->url = $connected_account_or_url; } else { $this->url = ''; } } /** * Returns the response from Instagram * * @return array|object * * @since 2.0/5.0 */ public function get_data() { if ( $this->is_wp_error() ) { return array(); } if ( ! empty($this->response['data'] ) ) { return $this->response['data']; } else { return $this->response; } } /** * Returns the error response and the url that was trying to be connected to * or false if no error * * @return array|bool * * @since 2.0/5.0 */ public function get_wp_error() { if ( $this->is_wp_error() ) { return array( 'response' => $this->response, 'url' => $this->url ); } else { return false; } } /** * Certain endpoints don't include the "next" URL so * this method allows using the "cursors->after" data instead * * @param $type * * @return bool * * @since 2.2.2/5.3.3 */ public function type_allows_after_paging( $type ) { return false; } /** * Returns the full url for the next page of the API request * * @param $type * * @return string * * @since 2.0/5.0 */ public function get_next_page( $type = '' ) { if ( ! empty( $this->response['pagination']['next_url'] ) ) { return $this->response['pagination']['next_url']; } elseif ( ! empty( $this->response['paging']['next'] ) ) { return $this->response['paging']['next']; } else { if ( $this->type_allows_after_paging( $type ) ) { if ( isset( $this->response['paging']['cursors']['after'] ) ) { return $this->response['paging']['cursors']['after']; } } return ''; } } /** * If url needs to be generated from the connected account, endpoint, * and params, this function is used to do so. * * @param $url */ public function set_url_from_args( $url ) { $this->url = $url; } /** * @return string * * @since 2.0/5.0 */ public function get_url() { return $this->url; } /** * If the server is unable to connect to the url, returns true * * @return bool * * @since 2.0/5.0 */ public function is_wp_error() { return is_wp_error( $this->response ); } /** * If the server can connect but Instagram returns an error, returns true * * @return bool * * @since 2.0/5.0 */ public function is_instagram_error( $response = false ) { if ( ! $response ) { $response = $this->response; } return (isset( $response['error'] )); } /** * Connect to the Instagram API and record the response * * @since 2.0/5.0 */ public function connect() { if ( empty( $this->url ) ) { $this->response = array(); return; } $args = array( 'timeout' => 20 ); $response = wp_remote_get( $this->url, $args ); /** * Api response for instagram connection * * @since 6.0.6 */ do_action( 'sbi_api_connect_response', $response, $this->url ); if ( ! is_wp_error( $response ) ) { // certain ways of representing the html for double quotes causes errors so replaced here. $response = json_decode( str_replace( '%22', '”', $response['body'] ), true ); if ( empty( $response ) ) { $response = array( 'error' => array( 'code' => 'unknown', 'message' => __( "An unknown error occurred when trying to connect to Instagram's API.", 'instagram-feed' ) ) ); } } $this->response = $response; } /** * Determines how and where to record an error from Instagram's API response * * @param array $response response from the API request * @param array $error_connected_account the connected account that is associated * with the error * @param string $request_type key used to determine the endpoint (ex. "header") * * @since 2.0/5.0 */ public static function handle_instagram_error( $response, $error_connected_account, $request_type ) { global $sb_instagram_posts_manager; delete_option( 'sbi_dismiss_critical_notice' ); $type = isset( $response['error']['code'] ) && (int)$response['error']['code'] === 18 ? 'hashtag_limit' : 'api'; $sb_instagram_posts_manager->add_error( $type, $response, $error_connected_account ); if ( $type === 'hashtag_limit' ) { $sb_instagram_posts_manager->maybe_set_display_error( $type, $response ); } } /** * Determines how and where to record an error connecting to a specified url * * @param $response * * @since 2.0/5.0 */ public static function handle_wp_remote_get_error( $response ) { global $sb_instagram_posts_manager; delete_option( 'sbi_dismiss_critical_notice' ); $sb_instagram_posts_manager->add_error( 'wp_remote_get', $response ); } /** * Determines how and where to record an error connecting to a specified url * * @since 2.0/5.0 */ public function has_encryption_error() { return isset( $this->encryption_error ) && $this->encryption_error; } /** * Sets the url for the API request based on the account information, * type of data needed, and additional parameters. * * Overwritten in the Pro version. * * @param array $connected_account connected account to be used in the request * @param string $endpoint_slug header or user * @param array $params additional params related to the request * * @since 2.0/5.0 * @since 2.2/5.3 added endpoints for the basic display API */ protected function set_url( $connected_account, $endpoint_slug, $params ) { $account_type = ! empty( $connected_account['type'] ) ? $connected_account['type'] : 'personal'; $num = ! empty( $params['num'] ) ? (int) $params['num'] : 33; if ( $account_type === 'basic' || $account_type === 'personal' ) { $access_token = sbi_maybe_clean( $connected_account['access_token'] ); if ( strpos( $access_token, 'IG' ) !== 0 ) { $this->encryption_error = true; $url = ''; } else { if ( $endpoint_slug === 'access_token' ) { $url = 'https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=' . $access_token; } elseif ( $endpoint_slug === 'header' ) { $url = 'https://graph.instagram.com/me?fields=id,username,media_count,account_type&access_token=' . $access_token; } else { $num = min( $num, 200 ); $url = 'https://graph.instagram.com/' . $connected_account['user_id'] . '/media?fields=media_url,thumbnail_url,caption,id,media_type,timestamp,username,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit=' . $num . '&access_token=' . $access_token; } } } else { $access_token = sbi_maybe_clean( $connected_account['access_token'] ); if ( strpos( $access_token, 'EA' ) !== 0 ) { $this->encryption_error = true; $url = ''; } else { if ( 'header' === $endpoint_slug ) { $url = 'https://graph.facebook.com/' . $connected_account['user_id'] . '?fields=biography,id,username,website,followers_count,media_count,profile_picture_url,name&access_token=' . sbi_maybe_clean( $connected_account['access_token'] ); } else { $num = min( $num, 200 ); $url = 'https://graph.facebook.com/' . $connected_account['user_id'] . '/media?fields=media_url,media_product_type,thumbnail_url,caption,id,media_type,timestamp,username,comments_count,like_count,permalink,children%7Bmedia_url,id,media_type,timestamp,permalink,thumbnail_url%7D&limit=' . $num . '&access_token=' . sbi_maybe_clean( $connected_account['access_token'] ); } } } $this->set_url_from_args( $url ); } } inc/class-sb-instagram-parse.php000064400000030320150515074560012636 0ustar00init(); $carousel_item_post = $single->get_post(); if ( isset( $carousel_item_post['thumbnail_url'] ) ) { $media = $carousel_item_post['thumbnail_url']; } elseif ( isset( $carousel_item_post['media_url'] ) && strpos( $carousel_item_post['media_url'], '.mp4' ) === false ) { $media = $carousel_item_post['media_url']; } $full_size = $media; } } $i++; } return $full_size; } else { if ( ! class_exists( 'SB_Instagram_Single' ) ) { return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } // attempt to get $permalink = self::fix_permalink( self::get_permalink( $post ) ); $single = new SB_Instagram_Single( $permalink ); $single->init(); $post = $single->get_post(); if ( isset( $post['thumbnail_url'] ) ) { return $post['thumbnail_url']; } elseif ( isset( $post['media_url'] ) && strpos( $post['media_url'], '.mp4' ) === false ) { return $post['media_url']; } return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } } else { if ( isset( $post['media_url'] ) ) { return $post['media_url']; } $permalink = self::fix_permalink( self::get_permalink( $post ) ); $single = new SB_Instagram_Single( $permalink ); $single->init(); $maybe_post = $single->get_post(); if ( isset( $maybe_post['media_url'] ) ) { return $maybe_post['media_url']; } elseif ( isset( $maybe_post['thumbnail_url'] ) ) { return $maybe_post['thumbnail_url']; } return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } } } /** * Uses the existing data for the indvidual instagram post to * set the best image sources for each resolution size. Due to * random bugs or just how the API works, different post types * need special treatment. * * @param array $post * @param array $resized_images * * @return array * * @since 2.0/5.0 * @since 2.1.3/5.2.3 added 'd' element as a default backup from the API */ public static function get_media_src_set( $post, $resized_images = array() ) { $full_size = self::get_media_url( $post ); $media_urls = array( 'd' => self::get_media_url( $post ), '150' => '', '320' => '', '640' => '' ); $account_type = isset( $post['images'] ) ? 'personal' : 'business'; if ( $account_type === 'personal' ) { $media_urls['150'] = $post['images']['thumbnail']['url']; $media_urls['320'] = $post['images']['low_resolution']['url']; $media_urls['640'] = $post['images']['standard_resolution']['url']; } else { $post_id = self::get_post_id( $post ); $media_urls['640'] = $full_size; $media_urls['150'] = $full_size; $media_urls['320'] = $full_size; // use resized images if exists if ( isset( $resized_images[ $post_id ]['id'] ) && $resized_images[ $post_id ]['id'] !== 'pending' && $resized_images[ $post_id ]['id'] !== 'video' && $resized_images[ $post_id ]['id'] !== 'error' ) { if ( isset( $resized_images[ $post_id ]['sizes']['full'] ) ) { $media_urls['640'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'full.jpg'; } if ( isset( $resized_images[ $post_id ]['sizes']['low'] ) ) { $media_urls['320'] = sbi_get_resized_uploads_url() . $resized_images[ $post_id ]['id'] . 'low.jpg'; } } } return $media_urls; } /** * A default can be set in the case that the user doesn't use captions * for posts as this is also used as the alt text for the image. * * @param $post * @param string $default * * @return string * * @since 2.0/5.0 */ public static function get_caption( $post, $default = '' ) { $caption = $default; if ( ! empty( $post['caption'] ) && ! is_array( $post['caption'] ) ) { $caption = $post['caption']; } elseif ( ! empty( $post['caption']['text'] ) ) { $caption = $post['caption']['text']; } $video_title = self::get_video_title( $post ); if ( ! empty( $video_title ) ) { $caption = $video_title . '. ' . $caption; } return $caption; } /** * @param array $header_data * * @return string * * @since 2.0/5.0 */ public static function get_username( $header_data ) { if ( isset( $header_data['username'] ) ) { return $header_data['username']; } elseif ( isset( $header_data['user'] ) ) { return $header_data['user']['username']; } elseif ( isset( $header_data['data'] ) ) { return $header_data['data']['username']; } return ''; } /** * @param array $header_data * @param array $settings * * @return string * * @since 2.0/5.0 * @since 2.2/5.3 added support for a custom avatar in settings */ public static function get_avatar( $header_data, $settings = array( 'favor_local' => false ), $is_header_attr = false ) { if ( $is_header_attr ) { return self::get_avatar_url( $header_data ); } if ( ! empty( $settings['customavatar'] ) ) { return $settings['customavatar']; } elseif ( ! empty( $header_data['local_avatar_url'] ) ) { return $header_data['local_avatar_url']; } elseif ( ! empty( $header_data['local_avatar'] ) && is_string( $header_data['local_avatar'] ) ) { return $header_data['local_avatar']; } else { if ( ! SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) || $is_header_attr ) { if ( isset( $header_data['profile_picture'] ) ) { return $header_data['profile_picture']; } elseif ( isset( $header_data['profile_picture_url'] ) ) { return $header_data['profile_picture_url']; } elseif ( isset( $header_data['user'] ) ) { return $header_data['user']['profile_picture']; } elseif ( isset( $header_data['data'] ) ) { return $header_data['data']['profile_picture']; } } else { return trailingslashit( SBI_PLUGIN_URL ) . 'img/thumb-placeholder.png'; } } return ''; } /** * The full name attached to the user account * * @param array $header_data * * @return string * * @since 2.0/5.0 */ public static function get_name( $header_data ) { if ( isset( $header_data['name'] ) ) { return $header_data['name']; } elseif ( isset( $header_data['data']['full_name'] ) ) { return $header_data['data']['full_name']; } return self::get_username( $header_data ); } /** * Account bio/description used in header * * @param $header_data * * @return string * * @since 2.0.1/5.0 * @since 2.2/5.3 added support for a custom bio in settings */ public static function get_bio( $header_data, $settings = array() ) { $customizer = $settings['customizer']; if ( $customizer ) { return '{{$parent.getHeaderBio()}}'; } else { if ( ! empty( $settings['custombio'] ) ) { return $settings['custombio']; } elseif ( isset( $header_data['data']['bio'] ) ) { return $header_data['data']['bio']; } elseif ( isset( $header_data['bio'] ) ) { return $header_data['bio']; } elseif ( isset( $header_data['biography'] ) ) { return $header_data['biography']; } return ''; } } /** * There seems to be occasional bugs with the Instagram API * and permalinks. This corrects it. * * @param string $permalink * * @return string * * @since 2.0/5.0 */ public static function fix_permalink( $permalink ) { if ( substr_count( $permalink, '/' ) > 5 ) { $permalink_array = explode( '/', $permalink ); $perm_id = $permalink_array[ count( $permalink_array ) - 2 ]; $permalink = 'https://www.instagram.com/p/' . $perm_id . '/'; } return $permalink; } /** * New in IG Graph API 10.0. A title for IGTV posts * * @param array $post * * @return string * * @since 2.9/5.12 */ public static function get_video_title( $post ) { if ( isset( $post['video_title'] ) ) { return $post['video_title']; } return ''; } /** * New in IG Graph API 10.0 * * @param array $post * * @return string * * @since 2.9/5.12 */ public static function get_media_product_type( $post ) { if ( isset( $post['media_product_type'] ) ) { return strtolower( $post['media_product_type'] ); } // get media_type and permalink and search for reel in permalink. $media_type = self::get_media_type( $post ); $permalink = self::get_permalink( $post ); if ( $media_type === 'video' && strpos( $permalink, 'https://www.instagram.com/reel/' ) !== false ) { return 'reels'; } return 'feed'; } /** * Get the avatar URL from the API response * * @param array $account_info * * @return string * * @since 6.0 */ public static function get_avatar_url( $account_info ) { if ( isset( $account_info['profile_picture'] ) ) { return $account_info['profile_picture']; } elseif ( isset( $account_info['profile_picture_url'] ) ) { return $account_info['profile_picture_url']; } elseif ( isset( $account_info['user'] ) ) { return $account_info['user']['profile_picture']; } elseif ( isset( $account_info['data'] ) ) { return $account_info['data']['profile_picture']; } return ''; } } inc/Builder/SBI_Theme_CSS.php000064400000014753150515074560011705 0ustar00file = $file; } /** * Whether or not a cache exists for this stylesheet. Updates daily or when the theme's stylesheet changes * * @return bool * * @since 6.0 */ public function is_cached() { $stored_styles = get_option( 'sbi_theme_styles', array( 'file' => '', 'last_checked' => 0, 'styles' => array() ) ); if ( empty( $stored_styles['file'] ) || $stored_styles['file'] !== $this->file ) { return false; } if ( empty( $stored_styles['last_checked'] ) || $stored_styles['last_checked'] < (time() - DAY_IN_SECONDS) ) { return false; } $this->styles = $stored_styles['styles']; return true; } /** * Stores the styles in a wp_option * * @return bool * * @since 6.0 */ public function cache() { $stored_styles = get_option( 'sbi_theme_styles', array( 'file' => '', 'last_checked' => 0, 'styles' => array() ) ); $stored_styles['file'] = $this->file; $stored_styles['styles'] = $this->styles; $stored_styles['last_checked'] = time(); return update_option( 'sbi_theme_styles', $stored_styles, false ); } /** * @return array * * @since 6.0 */ public function get_styles() { return $this->styles; } /** * Makes an HTTP request to get the contents of the stylesheet * * @since 6.0 */ public function load_css() { $url = $this->file; $args = array( 'timeout' => 60, ); $response = wp_remote_get( esc_url_raw( $url ), $args ); if ( ! is_wp_error( $response ) ) { // certain ways of representing the html for double quotes causes errors so replaced here. $this->css = $response['body']; } else { $this->css = false; } } /** * Uses a regex to detect selectors and styles and coverts them to key => value pairs * * @return bool * * @since 6.0 */ public function parse() { if ( empty( $this->css ) ) { return false; } $css = $this->css; preg_match_all( '/(?ims)([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/', $css, $arr); $result = array(); foreach ( $arr[0] as $i => $x ){ $selector = trim( $arr[1][ $i ] ); $rules = explode( ';', trim( $arr[2][ $i ] ) ); $rules_arr = array(); foreach ( $rules as $strRule ) { if ( !empty( $strRule ) ) { $rule = explode( ":", $strRule ); $rule_0 = isset( $rule[0] ) ? $rule[0] : 'null'; $rule_1 = isset( $rule[1] ) ? $rule[1] : ''; $rules_arr[ trim($rule_0) ] = trim( $rule_1 ); } } $selectors = explode(',', trim( $selector ) ); foreach ( $selectors as $strSel ) { if ( ! isset( $result[ $strSel ] ) ) { $result[ $strSel ] = $rules_arr; } else { $result[ $strSel . '_2' ] = $rules_arr; } } } $this->parsed = $result; } /** * Looks for styles based on specified selectors that are used * in generating the style HTML * * @return array * * @since 6.0 */ public function find_styles() { if ( empty( $this->css ) ) { return array(); } foreach ( $this->parsed as $selector => $property_array ) { foreach ( $property_array as $property => $style ) { $this->process( $selector, $property, $style ); } } } /** * Loop through all selectors and see if they can be used in our generated * style HTML * * @param string $selector * @param string $property * @param string $style * * @since 6.0 */ public function process( $selector, $property, $style ) { $selector = trim( $selector ); if ( $selector === 'body' ) { if ( in_array( $property, array( 'color', 'background-color', 'background', 'font-size' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === 'a' ) { if ( in_array( $property, array( 'color', 'font-weight', 'text-decoration' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === 'a:hover' ) { if ( in_array( $property, array( 'color', 'font-weight', 'text-decoration' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === 'p' ) { if ( in_array( $property, array( 'color', 'font-weight', 'font-size' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === 'h3' ) { if ( in_array( $property, array( 'color', 'font-weight', 'font-size' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === '.entry-content' ) { if ( in_array( $property, array( 'color', 'font-size' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } elseif ( $selector === '.entry-content a' ) { if ( in_array( $property, array( 'color', 'font-weight', 'text-decoration' ), true ) ) { if ( ! isset( $this->styles[ $selector ]['properties'][ $property ]['style'] ) ) { $this->styles[ $selector ]['properties'][ $property ]['style'] = $style; } } } } /** * Creates the actual style HTML as a string * * @return string * * @since 6.0 */ public function generate_style_html() { if ( empty( $this->styles ) ) { return ''; } $wrap_selector = self::WRAP_SELECTOR; $html = ''; return $html; } } inc/Builder/SBI_Feed_Saver_Manager.php000064400000056265150515074560013574 0ustar00 $source_ids ); $source_query = SBI_Db::source_query( $args ); $sources = array(); if ( ! empty( $source_query ) ) { foreach ( $source_query as $source ) { $sources[] = $source['account_id']; } } $settings_data['sources'] = $sources; if ( $feed_id !== 'legacy' ) { unset( $settings_data['sources'] ); $settings_data['id'] = implode(',', $sources ); } else { if ( isset( $settings_data['feed'] ) ) { unset( $settings_data['feed'] ); } $settings_data['id'] = implode(',', $source_ids ); \SB_Instagram_Cache::clear_legacy(); } $feed_saver = new SBI_Feed_Saver( $feed_id ); $feed_saver->set_feed_name( $feed_name ); $settings_data = self::filter_save_data( $settings_data ); $feed_saver->set_data( $settings_data ); $return = array( 'success' => false, 'feed_id' => false ); if ( $feed_saver->update_or_insert() ) { $return = array( 'success' => true, 'feed_id' => $feed_saver->get_feed_id() ); if($is_new_feed){ echo wp_json_encode( $return ); wp_die(); } else{ $feed_cache = new \SB_Instagram_Cache( $feed_id ); $feed_cache->clear( 'all' ); $feed_cache->clear( 'posts' ); echo wp_json_encode( $return ); wp_die(); } } } /** * Retrieve comments AJAX call * * @since 6.0 */ public static function retrieve_comments() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } wp_send_json_success(); } /** * Clear comments cache AJAX call * * @since 6.0 */ public static function clear_comments_cache() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $manager = new \SB_Instagram_Data_Manager(); $manager->delete_comments_data(); echo "success"; wp_die(); } /** * Used in an AJAX call to delete feeds from the Database * $_POST data. * * @since 6.0 */ public static function delete_feed() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if ( ! empty( $_POST['feeds_ids'] ) && is_array( $_POST['feeds_ids'] )) { SBI_Db::delete_feeds_query( $_POST['feeds_ids'] ); } } /** * Used in an AJAX call to delete Soureces from the Database * $_POST data. * * @since 6.0 */ public static function delete_source() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if ( ! empty( $_POST['source_id'] ) ) { if ( isset( $_POST['username'] ) && ! empty( $_POST['username'] ) ) { $username = sanitize_text_field( $_POST['username'] ); \SB_Instagram_Connected_Account::delete_local_avatar( $username ); } $source_id = absint( $_POST['source_id'] ); SBI_Db::delete_source_query( $source_id ); } } public static function recache_feed() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $feed_id = sanitize_key( $_POST['feedID'] ); $feed_cache = new \SB_Instagram_Cache( $feed_id ); $feed_cache->clear( 'all' ); $feed_cache->clear( 'posts' ); } /** * Used in an AJAX call to delete a feed cache from the Database * $_POST data. * * @since 6.0 */ public static function clear_single_feed_cache() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $feed_id = sanitize_key( $_POST['feedID'] ); if ( $feed_id === 'legacy' ) { \SB_Instagram_Cache::clear_legacy( true ); } else { $feed_cache = new \SB_Instagram_Cache( $feed_id ); $feed_cache->clear( 'all' ); $feed_cache->clear( 'posts' ); } SBI_Feed_Saver_Manager::feed_customizer_fly_preview(); wp_die(); } /** * Used in an AJAX call to duplicate a Feed * $_POST data. * * @since 6.0 */ public static function duplicate_feed() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if ( ! empty( $_POST['feed_id'] ) ) { SBI_Db::duplicate_feed_query( sanitize_key( $_POST['feed_id'] ) ); } } /** * Import a feed from JSON data * * @since 6.0 */ public static function importer() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if ( ! empty( $_POST['feed_json'] ) && strpos( $_POST['feed_json'], '{' ) === 0 ) { echo json_encode( SBI_Feed_Saver_Manager::import_feed( stripslashes( $_POST['feed_json'] ) ) ); } else { echo json_encode( array( 'success' => false, 'message' => __( 'Invalid JSON. Must have brackets "{}"', 'instagram-feed' ) ) ); } wp_die(); } /** * Used To check if it's customizer Screens * Returns Feed info or false! * * @param bool $include_comments * * @return array|bool * * @since 6.0 */ public static function maybe_feed_customizer_data( $include_comments = false ) { if ( isset( $_GET['feed_id'] ) ){ $feed_id = sanitize_key( $_GET['feed_id'] ); $feed_saver = new SBI_Feed_Saver( $feed_id ); $settings = $feed_saver->get_feed_settings(); $feed_db_data = $feed_saver->get_feed_db_data(); if ( $settings !== false ){ $return = array( 'feed_info' => $feed_db_data, 'headerData' => $feed_db_data, 'settings' => $settings, 'posts' => array() ); if ( intval( $feed_id ) > 0 ) { $instagram_feed_settings = new \SB_Instagram_Settings( array( 'feed' => $feed_id, 'customizer' => true ), sbi_defaults() ); } else { $instagram_feed_settings = new \SB_Instagram_Settings( array(), sbi_get_database_settings() ); } $instagram_feed_settings->set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $transient_name = $instagram_feed_settings->get_transient_name(); $settings = $instagram_feed_settings->get_settings(); $feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms(); if ( $feed_id === 'legacy' ) { $transient_name = 'sbi_*legacy'; } $instagram_feed = new \SB_Instagram_Feed( $transient_name ); $instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings ); if ( $instagram_feed->regular_cache_exists() ) { $instagram_feed->set_post_data_from_cache(); if ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } } else { while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) { $instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } if ( ! $instagram_feed->should_use_backup() ) { $instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); } elseif ( $instagram_feed->should_cache_error() ) { $cache_time = min( $instagram_feed_settings->get_cache_time_in_seconds(), 15 * 60 ); $instagram_feed->cache_feed_data( $cache_time, false ); } } $return['posts'] = $instagram_feed->get_post_data(); $instagram_feed->set_remote_header_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); $header_data = $instagram_feed->get_header_data(); if ( sbi_is_pro_version() && $settings['stories'] && ! empty( $header_data ) ) { $instagram_feed->set_remote_stories_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() ); } $instagram_feed->cache_header_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] ); if ( ! empty( $header_data ) && \SB_Instagram_Connected_Account::local_avatar_exists( $header_data['username'] ) ) { $header_data['local_avatar_url'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $header_data['username'] ); $header_data['local_avatar'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $header_data['username'] ); } else { $header_data['local_avatar'] = false; } $header_data['local_avatar'] = false; $return['header'] = $header_data; $return['headerData'] = $header_data; return $return; } } return false; } /** * Used to retrieve Feed Posts for preview screen * Returns Feed info or false! * * * * @since 6.0 */ public static function feed_customizer_fly_preview() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if( isset( $_POST['feedID'] ) && isset( $_POST['previewSettings'] ) ){ $feed_id = sanitize_key( $_POST['feedID'] ); $preview_settings = $_POST['previewSettings']; $feed_name = sanitize_text_field( wp_unslash( $_POST['feedName'] ) ); if(isset($_POST['moderationShoppableMode']) && $_POST['moderationShoppableMode'] == true){ $preview_settings['num'] = 10; $preview_settings['layout'] = 'grid'; $preview_settings['cols'] = 4; $preview_settings['offset'] = intval($_POST['offset']) * 10; $preview_settings['enablemoderationmode'] = false; $preview_settings['shoppablelist'] = isset( $preview_settings['shoppablelist'] ) ? json_encode($preview_settings['shoppablelist']) : []; $preview_settings['moderationlist'] = isset( $preview_settings['moderationlist'] ) ? json_encode($preview_settings['moderationlist']) : []; } if ( $feed_id === 'legacy' ) { \SB_Instagram_Cache::clear_legacy( true ); } else { $feed_cache = new \SB_Instagram_Cache( $feed_id ); $feed_cache->clear( 'all' ); $feed_cache->clear( 'posts' ); } $feed_saver = new SBI_Feed_Saver( $feed_id ); $feed_saver->set_feed_name( $feed_name ); $feed_saver->set_data( $preview_settings ); $atts = SBI_Feed_Builder::add_customizer_att( [ 'feed' => $feed_id, 'customizer' => true ] ); if ( ! empty( $preview_settings['id'] ) ) { $preview_settings['id'] = implode( ',', $preview_settings['id'] ); if ( isset( $preview_settings['user'] ) ) { unset( $preview_settings['user'] ); } } $return['feed_html'] = display_instagram( $atts, $preview_settings ); echo $return['feed_html']; } wp_die(); } /** * Used in AJAX call to return settings for an existing feed. * * @since 6.0 */ public static function get_feed_settings() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $feed_id = ! empty( $_POST['feed_id'] ) ? sanitize_key( $_POST['feed_id'] ) : false; if ( ! $feed_id ) { wp_die( 'no feed id' ); } $feed_saver = new SBI_Feed_Saver( $feed_id ); $settings = $feed_saver->get_feed_settings(); $return = array( 'settings' => $settings, 'feed_html' => '' ); if ( isset( $_POST['include_post_set'] ) && ! empty( $_POST['include_post_set'] ) ) { $atts = SBI_Feed_Builder::add_customizer_att( [ 'feed' => $return['feed_id'] ] ); $return['feed_html'] = display_instagram( $atts ); } echo sbi_json_encode( $return ); wp_die(); } /** * Get a list of feeds with a limit and offset like a page * * @since 6.0 */ public static function get_feed_list_page() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $args = array( 'page' => (int)$_POST['page'] ); $feeds_data = SBI_Feed_Builder::get_feed_list($args); echo sbi_json_encode( $feeds_data ); wp_die(); } /** * Get a list of locations with a limit and offset like a page * * @since 6.0 */ public static function get_locations_page() { check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $args = array( 'page' => (int)$_POST['page'] ); if ( ! empty( $_POST['is_legacy'] ) ) { $args['feed_id'] = sanitize_key( $_POST['feed_id'] ); } else { $args['feed_id'] = '*' . (int)$_POST['feed_id']; } $feeds_data = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); if ( count( $feeds_data ) < SBI_Db::RESULTS_PER_PAGE ) { $args['html_location'] = array( 'footer', 'sidebar', 'header' ); $args['group_by'] = 'html_location'; $args['page'] = 1; $non_content_data = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); $feeds_data = array_merge( $feeds_data, $non_content_data ); } echo sbi_json_encode( $feeds_data ); wp_die(); } /** * Return a single JSON string for importing a feed * * @param int $feed_id * * @return string * * @since 6.0 */ public static function get_export_json( $feed_id ) { $feed_saver = new SBI_Feed_Saver( $feed_id ); $settings = $feed_saver->get_feed_settings(); return sbi_json_encode( $settings ); } /** * All export strings for all feeds on the first 'page' * * @return array * * @since 6.0 */ public static function get_all_export_json() { $args = array( 'page' => 1 ); $feeds_data = SBI_Db::feeds_query( $args ); $return = array(); foreach ( $feeds_data as $single_feed ) { $return[ $single_feed['id'] ] = SBI_Feed_Saver_Manager::get_export_json( $single_feed['id'] ); } return $return; } /** * Use a JSON string to import a feed with settings and sources. The return * is whether or not the import was successful * * @param string $json * * @return array * * @since 6.0 */ public static function import_feed( $json ) { $settings_data = json_decode( $json, true ); $return = array( 'success' => false, 'message' => '' ); if ( empty( $settings_data['sources'] ) ) { $return['message'] = __( 'No feed source is included. Cannot upload feed.', 'instagram-feed' ); return $return; } $sources = $settings_data['sources']; unset( $settings_data['sources'] ); $settings_source = array(); foreach ( $sources as $source ) { if ( isset( $source['user_id'] ) ) { $source['account_id'] = $source['user_id']; $source['id'] = $source['user_id']; } if ( isset( $source['account_id'] ) ) { if ( isset( $source['record_id'] ) ) { unset( $source['record_id'] ); } $settings_source[] = $source['account_id']; // don't update or insert the access token if there is an API error if ( ! isset( $header_details->error ) ) { SBI_Source::update_or_insert( $source ); } } } $settings_data['sources'] = $settings_source; /* unset pro features if exists */ $settings_data = self::filter_save_data( $settings_data ); $feed_saver = new SBI_Feed_Saver( false ); $feed_saver->set_data( $settings_data ); if ( $feed_saver->update_or_insert() ) { $return = array( 'success' => true, 'feed_id' => $feed_saver->get_feed_id() ); return $return; } else { $return['message'] = __( 'Could not import feed. Please try again', 'instagram-feed' ); } return $return; } /** * Determines what table and sanitization should be used * when handling feed setting data. * * TODO: Add settings that need something other than sanitize_text_field * * @param string $key * * @return array * * @since 6.0 */ public static function get_data_type( $key ) { switch ( $key ) { case 'sources' : $return = array( 'table' => 'feed_settings', 'sanitization' => 'sanitize_text_field' ); break; case 'feed_title' : $return = array( 'table' => 'feeds', 'sanitization' => 'sanitize_text_field' ); break; case 'feed_name' : $return = array( 'table' => 'feeds', 'sanitization' => 'sanitize_text_field' ); break; case 'status' : $return = array( 'table' => 'feeds', 'sanitization' => 'sanitize_text_field' ); break; case 'author' : $return = array( 'table' => 'feeds', 'sanitization' => 'int' ); break; default: $return = array( 'table' => 'feed_settings', 'sanitization' => 'sanitize_text_field' ); break; } return $return; } /** * Uses the appropriate sanitization function and returns the result * for a value * * @param string $type * @param int|string $value * * @return int|string * * @since 6.0 */ public static function sanitize( $type, $value ) { switch ( $type ) { case 'int' : $return = intval( $value ); break; case 'boolean' : $return = self::cast_boolean($value); break; default: $return = sanitize_text_field( $value ); break; } return $return; } /** * Check if boolean * for a value * * @param string $type * @param int|string $value * * @return int|string * * @since 6.0 */ public static function is_boolean( $value ) { return ( $value === 'true' || $value === 'false' || is_bool($value) ) ? true : false; } public static function cast_boolean( $value ) { if($value === 'true' || $value === true || $value === 'on') return true; return false; } public static function filter_save_data( $save_data ) { if ( sbi_is_pro_version() ) { return $save_data; } $unsets = array( 'hoverdisplay', 'igtvposts', 'lightboxcomments', 'numcomments', 'stories', 'videosposts', 'videotypes', 'disablelightbox' ); foreach ( $unsets as $unset ) { if ( isset( $save_data[ $unset ] ) ) { unset( $save_data[ $unset ] ); } } return $save_data; } /** * Update Personal Account Info * Setting Avatar + Bio * * @return json * * @since 6.0.8 */ public static function sbi_update_personal_account(){ check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if( isset( $_FILES['avatar']['tmp_name'] ) && isset( $_POST['username'] ) ) { $account_avatar = sanitize_text_field( $_FILES['avatar']['tmp_name'] ); $username = sanitize_text_field( $_POST['username'] ); $created = \SB_Instagram_Connected_Account::create_local_avatar( $username, $account_avatar ); \SB_Instagram_Connected_Account::update_local_avatar_status( $username, $created ); } if( isset( $_POST['bio'] ) && isset( $_POST['id'] ) ){ $account_bio = sanitize_text_field( stripslashes( $_POST['bio'] ) ); $id = sanitize_text_field( wp_unslash( $_POST['id'] ) ); SBI_Source::update_personal_account_bio( $id, $account_bio ); } $response = array( 'success' => true, 'sourcesList' => SBI_Feed_Builder::get_source_list() ); echo sbi_json_encode( $response ); wp_die(); } } inc/Builder/SBI_Feed_Saver.php000064400000040240150515074560012124 0ustar00is_legacy = true; $this->insert_id = 0; } else { $this->is_legacy = false; $this->insert_id = $insert_id; } } /** * Feed insert ID if it exists * * @return bool|int * * @since 6.0 */ public function get_feed_id() { if ( $this->is_legacy ) { return 'legacy'; } if ( ! empty( $this->insert_id ) ) { return $this->insert_id; } else { return false; } } /** * @param array $data * * @since 6.0 */ public function set_data( $data ) { $this->data = $data; } /** * @param string $feed_name * * @since 6.0 */ public function set_feed_name( $feed_name ) { $this->feed_name = $feed_name; } /** * @param array $feed_db_data * * @return array * * @since 6.0 */ public function get_feed_db_data() { return $this->feed_db_data; } /** * Adds a new feed if there is no associated feed * found. Otherwise updates the exiting feed. * * @return false|int * * @since 6.0 */ public function update_or_insert() { $this->sanitize_and_sort_data(); if ( $this->exists_in_database() ) { return $this->update(); } else { return $this->insert(); } } /** * Whether or not a feed exists with the * associated insert ID * * @return bool * * @since 6.0 */ public function exists_in_database() { if ( $this->is_legacy ) { return true; } if ( $this->insert_id === false ) { return false; } $args = array( 'id' => $this->insert_id ); $results = SBI_Db::feeds_query( $args ); return isset( $results[0] ); } /** * Inserts a new feed from sanitized and sorted data. * Some data is saved in the sbi_feeds table and some is * saved in the sbi_feed_settings table. * * @return false|int * * @since 6.0 */ public function insert() { if ( $this->is_legacy ) { return $this->update(); } if ( ! isset( $this->sanitized_and_sorted_data ) ) { return false; } $settings_array = SBI_Feed_Saver::format_settings( $this->sanitized_and_sorted_data['feed_settings'] ); $this->sanitized_and_sorted_data['feeds'][] = array( 'key' => 'settings', 'values' => array( sbi_json_encode( $settings_array ) ) ); if ( ! empty( $this->feed_name ) ) { $this->sanitized_and_sorted_data['feeds'][] = array( 'key' => 'feed_name', 'values' => array( $this->feed_name ) ); } $this->sanitized_and_sorted_data['feeds'][] = array( 'key' => 'status', 'values' => array( 'publish' ) ); $insert_id = SBI_Db::feeds_insert( $this->sanitized_and_sorted_data['feeds'] ); if ( $insert_id ) { $this->insert_id = $insert_id; return $insert_id; } return false; } /** * Updates an existing feed and related settings from * sanitized and sorted data. * * @return false|int * * @since 6.0 */ public function update() { if ( ! isset( $this->sanitized_and_sorted_data ) ) { return false; } $args = array( 'id' => $this->insert_id ); $settings_array = SBI_Feed_Saver::format_settings( $this->sanitized_and_sorted_data['feed_settings'] ); if ( $this->is_legacy ) { $to_save_json = sbi_json_encode( $settings_array ); return update_option( 'sbi_legacy_feed_settings', $to_save_json, false ); } $this->sanitized_and_sorted_data['feeds'][] = array( 'key' => 'settings', 'values' => array( sbi_json_encode( $settings_array ) ) ); $this->sanitized_and_sorted_data['feeds'][] = array( 'key' => 'feed_name', 'values' => [sanitize_text_field($this->feed_name)] ); $success = SBI_Db::feeds_update( $this->sanitized_and_sorted_data['feeds'], $args ); return $success; } /** * Converts settings that have been sanitized into an associative array * that can be saved as JSON in the database * * @param $raw_settings * * @return array * * @since 6.0 */ public static function format_settings( $raw_settings ) { $settings_array = array(); foreach ( $raw_settings as $single_setting ) { if ( count( $single_setting['values'] ) > 1 ) { $settings_array[ $single_setting['key'] ] = $single_setting['values']; } else { $settings_array[ $single_setting['key'] ] = isset( $single_setting['values'][0] ) ? $single_setting['values'][0] : ''; } } return $settings_array; } /** * Gets the Preview Settings * for the Feed Fly Preview * * @return array|bool * * @since 6.0 */ public function get_feed_preview_settings( $preview_settings ){ } /** * Retrieves and organizes feed setting data for easy use in * the builder * * @return array|bool * * @since 6.0 */ public function get_feed_settings() { if ( $this->is_legacy ) { if ( sbi_is_pro_version() ) { $instagram_feed_settings = new \SB_Instagram_Settings_Pro( array(), sbi_get_database_settings() ); } else { $instagram_feed_settings = new \SB_Instagram_Settings( array(), sbi_get_database_settings() ); } $instagram_feed_settings->set_feed_type_and_terms(); $instagram_feed_settings->set_transient_name(); $return = $instagram_feed_settings->get_settings(); $this->feed_db_data = array( 'id' => 'legacy', 'feed_name' => __( 'Legacy Feeds', 'instagram-feed' ), 'feed_title' => __( 'Legacy Feeds', 'instagram-feed' ), 'status' => 'publish', 'last_modified' => date( 'Y-m-d H:i:s' ), ); } else if ( empty( $this->insert_id ) ) { return false; } else { $args = array( 'id' => $this->insert_id, ); $settings_db_data = SBI_Db::feeds_query( $args ); if ( false === $settings_db_data || sizeof($settings_db_data) == 0) { return false; } $this->feed_db_data = array( 'id' => $settings_db_data[0]['id'], 'feed_name' => $settings_db_data[0]['feed_name'], 'feed_title' => $settings_db_data[0]['feed_title'], 'status' => $settings_db_data[0]['status'], 'last_modified' => $settings_db_data[0]['last_modified'], ); $return = json_decode( $settings_db_data[0]['settings'], true ); $return['feed_name'] = $settings_db_data[0]['feed_name']; } $return = wp_parse_args( $return, SBI_Feed_Saver::settings_defaults() ); if ( empty( $return['id'] ) ) { return $return; } if ( ! is_array( $return['id'] ) ) { $return['id'] = explode( ',', str_replace( ' ', '', $return['id'] ) ); } if ( ! is_array( $return['tagged'] ) ) { $return['tagged'] = explode( ',', str_replace( ' ', '', $return['tagged'] ) ); } if ( ! is_array( $return['hashtag'] ) ) { $return['hashtag'] = explode( ',', str_replace( ' ', '', $return['hashtag'] ) ); } $args = array( 'id' => $return['id'] ); $source_query = SBI_Db::source_query( $args ); $return['sources'] = array(); if ( ! empty( $source_query ) ) { foreach ( $source_query as $source ) { $user_id = $source['account_id']; $return['sources'][ $user_id ] = self::get_processed_source_data( $source ); } } else { $found_sources = array(); foreach ( $return['id'] as $id_or_slug ) { $maybe_source_from_connected = SBI_Source::maybe_one_off_connected_account_update( $id_or_slug ); if ( $maybe_source_from_connected ) { $found_sources[] = $maybe_source_from_connected; } } if ( ! empty( $found_sources ) ) { foreach ( $found_sources as $source ) { $user_id = $source['account_id']; $return['sources'][ $user_id ] = self::get_processed_source_data( $source ); } } else { $source_query = SBI_Db::source_query( $args ); if ( isset( $source_query[0] ) ) { $source = $source_query[0]; $user_id = $source['account_id']; $return['sources'][ $user_id ] = self::get_processed_source_data( $source ); } } } return $return; } public static function get_processed_source_data( $source ) { $encryption = new \SB_Instagram_Data_Encryption(); $user_id = $source['account_id']; $info = ! empty( $source['info'] ) ? json_decode( $encryption->decrypt( $source['info'] ), true ) : array(); $cdn_avatar_url = \SB_Instagram_Parse::get_avatar_url( $info ); $processed = array( 'record_id' => stripslashes( $source['id'] ), 'user_id' => $user_id, 'type' => stripslashes( $source['account_type'] ), 'privilege' => stripslashes( $source['privilege'] ), 'access_token' => stripslashes( $encryption->decrypt( $source['access_token'] ) ), 'username' => stripslashes( $source['username'] ), 'name' => stripslashes( $source['username'] ), 'info' => stripslashes( $encryption->decrypt( $source['info'] ) ), 'error' => stripslashes( $source['error'] ), 'expires' => stripslashes( $source['expires'] ), 'profile_picture' => $cdn_avatar_url, 'local_avatar_url' => \SB_Instagram_Connected_Account::maybe_local_avatar( $source['username'], $cdn_avatar_url ) ); return $processed; } /** * Retrieves and organizes feed setting data for easy use in * the builder * It will NOT get the settings from the DB, but from the Customizer builder * To be used for updating feed preview on the fly * * @return array|bool * * @since 6.0 */ public function get_feed_settings_preview( $settings_db_data ) { if ( false === $settings_db_data || sizeof($settings_db_data) == 0) { return false; } $return = $settings_db_data; $return = wp_parse_args( $return, SBI_Feed_Saver::settings_defaults() ); if ( empty( $return['sources'] ) ) { return $return; } $sources = []; foreach ($return['sources'] as $single_source) { array_push($sources, $single_source['account_id']); } $args = array( 'id' => $sources ); $source_query = SBI_Db::source_query( $args ); $return['sources'] = array(); if ( ! empty( $source_query ) ) { foreach ( $source_query as $source ) { $user_id = $source['account_id']; $return['sources'][ $user_id ] = self::get_processed_source_data( $source ); } } return $return; } /** * Default settings, $return_array equalling false will return * the settings in the general way that the "SBI_Shortcode" class, * "sbi_get_processed_options" method does * * @param bool $return_array * * @return array * * @since 6.0 */ public static function settings_defaults( $return_array = true ) { { $defaults = array( //V6 'customizer' => false, //Feed general 'type' => 'user', //user - hashtag - 'order' => 'recent', 'id' => [], 'hashtag' => [], 'tagged' => [], 'width' => '', 'widthunit' => '', 'widthresp' => true, 'height' => '', 'heightunit' => '', 'sortby' => 'none', 'disablelightbox' => true, 'captionlinks' => false, 'offset' => 0, 'num' => 20, 'apinum' => '', 'nummobile' => 20, 'cols' => 4, 'colstablet' => 2, 'colsmobile' => 1, 'disablemobile' => false, 'imagepadding' => '5', 'imagepaddingunit' => 'px', 'layout' => 'grid', //Lightbox comments 'lightboxcomments' => true, 'numcomments' => 20, //Photo hover styles 'hovereffect' => '', 'hovercolor' => '', 'hovertextcolor' => '', 'hoverdisplay' => 'username,date,instagram', //Item misc 'background' => '', 'imageres' => 'auto', 'media' => 'all', 'videotypes' => 'regular,igtv,reels', 'showcaption' => true, 'captionlength' => '', 'captioncolor' => '', 'captionsize' => '', 'showlikes' => true, 'likescolor' => '', 'likessize' => '13', 'hidephotos' => '', //Footer 'showbutton' => true, 'buttoncolor' => '', 'buttonhovercolor' => '', // to be tested 'buttontextcolor' => '', 'buttontext' => 'Load More', 'showfollow' => true, 'followcolor' => '#408bd1', 'followhovercolor' => '#359dff', // to be tested 'followtextcolor' => '', 'followtext' => 'Follow on Instagram', //Header 'showheader' => true, 'headertextsize' => '', //to be tested 'headercolor' => '', 'headerstyle' => 'standard', 'showfollowers' => false, 'showbio' => true, 'custombio' => '', 'customavatar' => '', 'headerprimarycolor' => '#517fa4', 'headersecondarycolor' => '#eeeeee', 'headersize' => 'medium', 'stories' => true, 'storiestime' => '', 'headeroutside' => false, 'class' => '', 'ajaxtheme' => '', 'excludewords' => '', 'includewords' => '', 'maxrequests' => 5, //Carousel 'carouselrows' => 1, 'carouselloop' => 'rewind', 'carouselarrows' => false, 'carouselpag' => true, 'carouselautoplay' => false, 'carouseltime' => 5000, //Highlight 'highlighttype' => 'pattern', 'highlightoffset' => 0, 'highlightpattern' => '', 'highlighthashtag' => '', 'highlightids' => '', //WhiteList 'whitelist' => '', //Load More on Scroll 'autoscroll' => false, 'autoscrolldistance' => '', //Permanent 'permanent' => false, 'accesstoken' => '', 'user' => '', //Misc 'feedid' => false, 'resizeprocess' => 'background', 'mediavine' => '', 'customtemplates' => false, 'moderationmode' => false, //NEWLY ADDED //TO BE CHECKED 'colstablet' => 2, 'colorpalette' => 'inherit', 'custombgcolor1' => '', 'customtextcolor1' => '', 'customtextcolor2' => '', 'customlinkcolor1' => '', 'custombuttoncolor1' => '', 'custombuttoncolor2' => '', 'photosposts' => true, 'videosposts' => true, 'igtvposts' => true, 'reelsposts' => true, 'shoppablefeed' => false, 'shoppablelist' => '{}', 'moderationlist' => '{"list_type_selected" : "allow", "allow_list" : [], "block_list" : [] }', 'customBlockModerationlist' => '', 'enablemoderationmode' => false, 'fakecolorpicker' => '' ); $defaults = SBI_Feed_Saver::filter_defaults( $defaults ); // some settings are comma separated and not arrays when the feed is created if ( $return_array ) { $settings_with_multiples = array( 'sources' ); foreach ( $settings_with_multiples as $multiple_key ) { if ( isset( $defaults[ $multiple_key ] ) ) { $defaults[ $multiple_key ] = explode( ',', $defaults[ $multiple_key ] ); } } } return $defaults; } } /** * Provides backwards compatibility for extensions * * @param array $defaults * * @return array * * @since 6.0 */ public static function filter_defaults( $defaults ) { return $defaults; } /** * Saves settings for legacy feeds. Runs on first update automatically. * * @since 6.0 */ public static function set_legacy_feed_settings() { $to_save = SBI_Post_Set::legacy_to_builder_convert(); $to_save_json = sbi_json_encode( $to_save ); update_option( 'sbi_legacy_feed_settings', $to_save_json, false ); } /** * Used for taking raw post data related to settings * an sanitizing it and sorting it to easily use in * the database tables * * @since 6.0 */ private function sanitize_and_sort_data() { $data = $this->data; $sanitized_and_sorted = array( 'feeds' => array(), 'feed_settings' => array() ); foreach ( $data as $key => $value ) { $data_type = SBI_Feed_Saver_Manager::get_data_type( $key ); $sanitized_values = array(); if ( is_array( $value ) ) { foreach ( $value as $item ) { $type = SBI_Feed_Saver_Manager::is_boolean( $item ) ? 'boolean' : $data_type['sanitization']; $sanitized_values[] = SBI_Feed_Saver_Manager::sanitize( $type , $item ); } } else { $type = SBI_Feed_Saver_Manager::is_boolean( $value ) ? 'boolean' : $data_type['sanitization']; $sanitized_values[] = SBI_Feed_Saver_Manager::sanitize( $type, $value ); } $single_sanitized = array( 'key' => $key, 'values' => $sanitized_values ); $sanitized_and_sorted[ $data_type['table'] ][] = $single_sanitized; } $this->sanitized_and_sorted_data = $sanitized_and_sorted; } } inc/Builder/SB_Builder_Customizer.php000064400000003101150515074560013615 0ustar00print_control_wrapper($editingType); } } }inc/Builder/SBI_Db.php000064400000057722150515074560010463 0ustar00prefix . 'sbi_sources'; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $page = 0; if ( isset( $args['page'] ) ) { $page = (int) $args['page'] - 1; unset( $args['page'] ); } $offset = max( 0, $page * 400 ); if ( empty( $args ) ) { $limit = 400; $sql = "SELECT s.id, s.account_id, s.account_type, s.privilege, s.access_token, s.username, s.info, s.error, s.expires, count(f.id) as used_in FROM $sources_table_name s LEFT JOIN $feeds_table_name f ON f.settings LIKE CONCAT('%', s.account_id, '%') GROUP BY s.id, s.account_id LIMIT $limit OFFSET $offset; "; $results = $wpdb->get_results( $sql, ARRAY_A ); if ( empty( $results ) ) { return array(); } $i = 0; foreach ( $results as $result ) { if ( (int) $result['used_in'] > 0 ) { $results[ $i ]['instances'] = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $feeds_table_name WHERE settings LIKE CONCAT('%', %s, '%') GROUP BY id LIMIT 100; ", $result['account_id'] ), ARRAY_A ); } $i++; } return $results; } if ( ! empty( $args['expiring'] ) ) { $sql = $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE account_type = 'personal' AND expires < %s AND last_updated < %s ORDER BY expires ASC LIMIT 5; ", gmdate( 'Y-m-d H:i:s', time() + SBI_REFRESH_THRESHOLD_OFFSET ), gmdate( 'Y-m-d H:i:s', time() - SBI_MINIMUM_INTERVAL ) ); return $wpdb->get_results( $sql, ARRAY_A ); } if ( ! empty( $args['username'] ) ) { return $wpdb->get_results( $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE username = %s; ", $args['username'] ), ARRAY_A ); } if ( isset( $args['access_token'] ) && ! isset( $args['id'] ) ) { return $wpdb->get_results( $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE access_token = %s; ", $args['access_token'] ), ARRAY_A ); } if ( ! isset( $args['id'] ) ) { return false; } if ( is_array( $args['id'] ) ) { $id_array = array(); foreach ( $args['id'] as $id ) { $id_array[] = esc_sql( $id ); } } elseif ( strpos( $args['id'], ',' ) !== false ) { $id_array = explode( ',', str_replace( ' ', '', esc_sql( $args['id'] ) ) ); } if ( isset( $id_array ) ) { $id_string = "'" . implode( "' , '", array_map( 'esc_sql', $id_array ) ) . "'"; } if ( ! empty( $args['all_business'] ) ) { $id_string = empty( $id_string ) ? '0' : $id_string; $sql = " SELECT * FROM $sources_table_name WHERE account_id IN ($id_string) OR account_type = 'business' "; return $wpdb->get_results( $sql, ARRAY_A ); } $privilege = ''; if ( ! empty( $privilege ) ) { if ( isset( $id_string ) ) { $sql = $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE account_id IN ($id_string) AND privilege = %s; ", $privilege ); } else { $sql = $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE account_id = %s AND privilege = %s; ", $args['id'], $privilege ); } } else { if ( isset( $id_string ) ) { $sql = " SELECT * FROM $sources_table_name WHERE account_id IN ($id_string); "; } else { $sql = $wpdb->prepare( " SELECT * FROM $sources_table_name WHERE account_id = %s; ", $args['id'] ); } } return $wpdb->get_results( $sql, ARRAY_A ); } /** * Update a source (connected account) * * @param array $to_update * @param array $where_data * * @return false|int * * @since 6.0 */ public static function source_update( $to_update, $where_data ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; $encryption = new \SB_Instagram_Data_Encryption(); $data = array(); $where = array(); $format = array(); $where_format = array(); if ( isset( $to_update['type'] ) ) { $data['account_type'] = $to_update['type']; $format[] = '%s'; } if ( isset( $to_update['privilege'] ) ) { $data['privilege'] = $to_update['privilege']; $format[] = '%s'; } if ( isset( $to_update['id'] ) ) { $where['account_id'] = $to_update['id']; $where_format[] = '%s'; } if ( isset( $to_update['access_token'] ) ) { $data['access_token'] = $encryption->maybe_encrypt( $to_update['access_token'] ); $format[] = '%s'; } if ( isset( $to_update['username'] ) ) { $data['username'] = $to_update['username']; $format[] = '%s'; } if ( isset( $to_update['info'] ) ) { $data['info'] = $encryption->maybe_encrypt( $to_update['info'] ); $format[] = '%s'; } if ( isset( $to_update['error'] ) ) { $data['error'] = $to_update['error']; $format[] = '%s'; } if ( isset( $to_update['expires'] ) ) { $data['expires'] = $to_update['expires']; $format[] = '%s'; } if ( isset( $to_update['last_updated'] ) ) { $data['last_updated'] = $to_update['last_updated']; $format[] = '%s'; } if ( isset( $to_update['author'] ) ) { $data['author'] = $to_update['author']; $format[] = '%d'; } if ( isset( $where_data['type'] ) ) { $where['account_type'] = $where_data['type']; $where_format[] = '%s'; } if ( isset( $where_data['privilege'] ) ) { $where['privilege'] = $where_data['privilege']; $where_format[] = '%s'; } if ( isset( $where_data['author'] ) ) { $where['author'] = $where_data['author']; $where_format[] = '%d'; } if ( isset( $where_data['id'] ) ) { $where['account_id'] = $where_data['id']; $where_format[] = '%s'; } if ( isset( $where_data['record_id'] ) ) { $where['id'] = $where_data['record_id']; $where_format[] = '%d'; } $affected = $wpdb->update( $sources_table_name, $data, $where, $format, $where_format ); return $affected; } /** * New source (connected account) data is added to the * sbi_sources table and the new insert ID is returned * * @param array $to_insert * * @return false|int * * @since 6.0 */ public static function source_insert( $to_insert ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; $encryption = new \SB_Instagram_Data_Encryption(); $data = array(); $format = array(); if ( isset( $to_insert['id'] ) ) { $data['account_id'] = $to_insert['id']; $format[] = '%s'; } if ( isset( $to_insert['type'] ) ) { $data['account_type'] = $to_insert['type']; $format[] = '%s'; } else { $data['account_type'] = 'page'; $format[] = '%s'; } if ( isset( $to_insert['privilege'] ) ) { $data['privilege'] = $to_insert['privilege']; $format[] = '%s'; } if ( isset( $to_insert['access_token'] ) ) { $data['access_token'] = $encryption->maybe_encrypt( $to_insert['access_token'] ); $format[] = '%s'; } if ( isset( $to_insert['username'] ) ) { $data['username'] = $to_insert['username']; $format[] = '%s'; } if ( isset( $to_insert['info'] ) ) { $data['info'] = $encryption->maybe_encrypt( $to_insert['info'] ); $format[] = '%s'; } if ( isset( $to_insert['error'] ) ) { $data['error'] = $to_insert['error']; $format[] = '%s'; } if ( isset( $to_insert['expires'] ) ) { $data['expires'] = $to_insert['expires']; $format[] = '%s'; } else { $data['expires'] = '2037-12-30 00:00:00'; $format[] = '%s'; } $data['last_updated'] = gmdate( 'Y-m-d H:i:s' ); $format[] = '%s'; if ( isset( $to_insert['author'] ) ) { $data['author'] = $to_insert['author']; $format[] = '%d'; } else { $data['author'] = get_current_user_id(); $format[] = '%d'; } return $wpdb->insert( $sources_table_name, $data, $format ); } /** * Query the to get feeds list for Elementor * * @return array * * @since 6.0 */ public static function elementor_feeds_query() { global $wpdb; $feeds_elementor = array(); $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $feeds_list = $wpdb->get_results( " SELECT id, feed_name FROM $feeds_table_name; " ); if ( ! empty( $feeds_list ) ) { foreach ( $feeds_list as $feed ) { $feeds_elementor[ $feed->id ] = $feed->feed_name; } } return $feeds_elementor; } /** * Count the sbi_feeds table * * @return int * * @since 6.0 */ public static function feeds_count() { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $results = $wpdb->get_results( "SELECT COUNT(*) AS num_entries FROM $feeds_table_name", ARRAY_A ); return isset( $results[0]['num_entries'] ) ? (int) $results[0]['num_entries'] : 0; } /** * Query the sbi_feeds table * * @param array $args * * @return array|bool * * @since 6.0 */ public static function feeds_query( $args = array() ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $page = 0; if ( isset( $args['page'] ) ) { $page = (int) $args['page'] - 1; unset( $args['page'] ); } $offset = max( 0, $page * self::RESULTS_PER_PAGE ); if ( isset( $args['id'] ) ) { $sql = $wpdb->prepare( " SELECT * FROM $feeds_table_name WHERE id = %d; ", $args['id'] ); } else { $sql = $wpdb->prepare( " SELECT * FROM $feeds_table_name LIMIT %d OFFSET %d;", self::RESULTS_PER_PAGE, $offset ); } return $wpdb->get_results( $sql, ARRAY_A ); } /** * Update feed data in the sbi_feed table * * @param array $to_update * @param array $where_data * * @return false|int * * @since 6.0 */ public static function feeds_update( $to_update, $where_data ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $data = array(); $where = array(); $format = array(); foreach ( $to_update as $single_insert ) { if ( $single_insert['key'] ) { $data[ $single_insert['key'] ] = $single_insert['values'][0]; $format[] = '%s'; } } if ( isset( $where_data['id'] ) ) { $where['id'] = $where_data['id']; $where_format = array( '%d' ); } elseif ( isset( $where_data['feed_name'] ) ) { $where['feed_name'] = $where_data['feed_name']; $where_format = array( '%s' ); } else { return false; } $data['last_modified'] = gmdate( 'Y-m-d H:i:s' ); $format[] = '%s'; $affected = $wpdb->update( $feeds_table_name, $data, $where, $format, $where_format ); return $affected; } /** * New feed data is added to the sbi_feeds table and * the new insert ID is returned * * @param array $to_insert * * @return false|int * * @since 6.0 */ public static function feeds_insert( $to_insert ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $data = array(); $format = array(); foreach ( $to_insert as $single_insert ) { if ( $single_insert['key'] ) { $data[ $single_insert['key'] ] = $single_insert['values'][0]; $format[] = '%s'; } } $data['last_modified'] = gmdate( 'Y-m-d H:i:s' ); $format[] = '%s'; $data['author'] = get_current_user_id(); $format[] = '%d'; $wpdb->insert( $feeds_table_name, $data, $format ); return $wpdb->insert_id; } /** * Query the sbi_feeds table * Porcess to define the name of the feed when adding new * * @param string $sourcename * * @return array|bool * * @since 6.0 */ public static function feeds_query_name( $sourcename ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $sql = $wpdb->prepare( "SELECT * FROM $feeds_table_name WHERE feed_name LIKE %s;", $wpdb->esc_like( $sourcename ) . '%' ); $count = count( $wpdb->get_results( $sql, ARRAY_A ) ); return ( $count === 0 ) ? $sourcename : $sourcename . ' (' . ( $count + 1 ) . ')'; } /** * Query to Remove Feeds from Database * * @param array $feed_ids_array * * @since 6.0 */ public static function delete_feeds_query( $feed_ids_array ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches'; $feed_ids_array = implode( ',', array_map( 'absint', $feed_ids_array ) ); $wpdb->query( "DELETE FROM $feeds_table_name WHERE id IN ($feed_ids_array)" ); $wpdb->query( "DELETE FROM $feed_caches_table_name WHERE feed_id IN ($feed_ids_array)" ); echo sbi_json_encode( SBI_Feed_Builder::get_feed_list() ); wp_die(); } /** * Query to Remove Source from Database * * @param array $source_id * * @since 6.0.6 */ public static function delete_source( $source_id ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; return $wpdb->query( $wpdb->prepare( "DELETE FROM $sources_table_name WHERE id = %d; ", $source_id ) ); } /** * Query to Remove Source from Database * * @param array $source_id * * @since 6.0 */ public static function delete_source_query( $source_id ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; $wpdb->query( $wpdb->prepare( "DELETE FROM $sources_table_name WHERE id = %d; ", $source_id ) ); echo sbi_json_encode( SBI_Feed_Builder::get_source_list() ); wp_die(); } /** * Query to Remove Source from Database * * @param array $source_id * * @since 6.0 */ public static function delete_source_by_account_id( $source_id ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; $wpdb->query( $wpdb->prepare( "DELETE FROM $sources_table_name WHERE account_id = %s; ", $source_id ) ); } /** * Query to Duplicate a Single Feed * * @param int $feed_id * * @since 6.0 */ public static function duplicate_feed_query( $feed_id ) { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $wpdb->query( $wpdb->prepare( "INSERT INTO $feeds_table_name (feed_name, settings, author, status) SELECT CONCAT(feed_name, ' (copy)'), settings, author, status FROM $feeds_table_name WHERE id = %d; ", $feed_id ) ); echo sbi_json_encode( SBI_Feed_Builder::get_feed_list() ); wp_die(); } /** * Get cache records in the sbi_feed_caches table * * @param array $args * * @return array|object|null */ public static function feed_caches_query( $args ) { global $wpdb; $feed_cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; if ( ! isset( $args['cron_update'] ) ) { $sql = " SELECT * FROM $feed_cache_table_name;"; } else { if ( ! isset( $args['additional_batch'] ) ) { $sql = $wpdb->prepare( " SELECT * FROM $feed_cache_table_name WHERE cron_update = 'yes' ORDER BY last_updated ASC LIMIT %d;", self::RESULTS_PER_CRON_UPDATE ); } else { $sql = $wpdb->prepare( " SELECT * FROM $feed_cache_table_name WHERE cron_update = 'yes' AND last_updated < %s ORDER BY last_updated ASC LIMIT %d;", gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ), self::RESULTS_PER_CRON_UPDATE ); } } return $wpdb->get_results( $sql, ARRAY_A ); } /** * Creates all database tables used in the new admin area in * the 6.0 update. * * TODO: Add error reporting * * @since 6.0 */ public static function create_tables( $include_charset_collate = true ) { if ( ! function_exists( 'dbDelta' ) ) { require_once ABSPATH . '/wp-admin/includes/upgrade.php'; } global $wpdb; $max_index_length = 191; $charset_collate = ''; if ( $include_charset_collate && method_exists( $wpdb, 'get_charset_collate' ) ) { // get_charset_collate introduced in WP 3.5 $charset_collate = $wpdb->get_charset_collate(); } $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; if ( $wpdb->get_var( "show tables like '$feeds_table_name'" ) !== $feeds_table_name ) { $sql = " CREATE TABLE $feeds_table_name ( id bigint(20) unsigned NOT NULL auto_increment, feed_name text NOT NULL default '', feed_title text NOT NULL default '', settings longtext NOT NULL default '', author bigint(20) unsigned NOT NULL default '1', status varchar(255) NOT NULL default '', last_modified datetime NOT NULL, PRIMARY KEY (id), KEY author (author) ) $charset_collate; "; $wpdb->query( $sql ); } $error = $wpdb->last_error; $query = $wpdb->last_query; $had_error = false; if ( $wpdb->get_var( "show tables like '$feeds_table_name'" ) !== $feeds_table_name ) { $had_error = true; } if ( ! $had_error ) { } $feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches'; if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) !== $feed_caches_table_name ) { $sql = ' CREATE TABLE ' . $feed_caches_table_name . " ( id bigint(20) unsigned NOT NULL auto_increment, feed_id varchar(255) NOT NULL default '', cache_key varchar(255) NOT NULL default '', cache_value longtext NOT NULL default '', cron_update varchar(20) NOT NULL default 'yes', last_updated datetime NOT NULL, PRIMARY KEY (id), KEY feed_id (feed_id($max_index_length)) ) $charset_collate;"; $wpdb->query( $sql ); } $error = $wpdb->last_error; $query = $wpdb->last_query; $had_error = false; if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) !== $feed_caches_table_name ) { $had_error = true; } if ( ! $had_error ) { } $sources_table_name = $wpdb->prefix . 'sbi_sources'; if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) !== $sources_table_name ) { $sql = ' CREATE TABLE ' . $sources_table_name . " ( id bigint(20) unsigned NOT NULL auto_increment, account_id varchar(255) NOT NULL default '', account_type varchar(255) NOT NULL default '', privilege varchar(255) NOT NULL default '', access_token varchar(1000) NOT NULL default '', username varchar(255) NOT NULL default '', info text NOT NULL default '', error text NOT NULL default '', expires datetime NOT NULL, last_updated datetime NOT NULL, author bigint(20) unsigned NOT NULL default '1', PRIMARY KEY (id), KEY account_type (account_type($max_index_length)), KEY author (author) ) $charset_collate;"; $wpdb->query( $sql ); } $error = $wpdb->last_error; $query = $wpdb->last_query; $had_error = false; if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) !== $sources_table_name ) { $had_error = true; } if ( ! $had_error ) { } } public static function create_sources_database() { // not needed } public static function clear_sbi_feed_caches() { global $wpdb; $feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches'; if ( $wpdb->get_var( "show tables like '$feed_caches_table_name'" ) === $feed_caches_table_name ) { $wpdb->query( "DELETE FROM $feed_caches_table_name" ); } } public static function clear_sbi_sources() { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; if ( $wpdb->get_var( "show tables like '$sources_table_name'" ) === $sources_table_name ) { $wpdb->query( "DELETE FROM $sources_table_name" ); } } public static function reset_tables() { global $wpdb; $feeds_table_name = $wpdb->prefix . 'sbi_feeds'; $wpdb->query( "DROP TABLE IF EXISTS $feeds_table_name" ); $feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches'; $wpdb->query( "DROP TABLE IF EXISTS $feed_caches_table_name" ); $sources_table_name = $wpdb->prefix . 'sbi_sources'; $wpdb->query( "DROP TABLE IF EXISTS $sources_table_name" ); } public static function reset_db_update() { update_option( 'sbi_db_version', 1.9 ); delete_option( 'sbi_legacy_feed_settings' ); // are there existing feeds to toggle legacy onboarding? $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( isset( $sbi_statuses_option['legacy_onboarding'] ) ) { unset( $sbi_statuses_option['legacy_onboarding'] ); } if ( isset( $sbi_statuses_option['support_legacy_shortcode'] ) ) { unset( $sbi_statuses_option['support_legacy_shortcode'] ); } global $wpdb; $table_name = $wpdb->prefix . 'usermeta'; $wpdb->query( " DELETE FROM $table_name WHERE `meta_key` LIKE ('sbi\_%') " ); $feed_locator_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR ); $results = $wpdb->query( " DELETE FROM $feed_locator_table_name WHERE feed_id LIKE '*%';" ); update_option( 'sbi_statuses', $sbi_statuses_option ); } public static function reset_legacy() { //Settings delete_option( 'sbi_statuses' ); delete_option( 'sb_instagram_settings' ); delete_option( 'sbi_ver' ); delete_option( 'sb_expired_tokens' ); delete_option( 'sbi_cron_report' ); delete_option( 'sb_instagram_errors' ); delete_option( 'sb_instagram_ajax_status' ); delete_option( 'sbi_db_version' ); // Clear backup caches global $wpdb; $table_name = $wpdb->prefix . 'options'; $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%!sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%sb_wlupdated_%') " ); //image resizing $upload = wp_upload_dir(); $posts_table_name = $wpdb->prefix . 'sbi_instagram_posts'; $feeds_posts_table_name = esc_sql( $wpdb->prefix . 'sbi_instagram_feeds_posts' ); $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . '*' ); // get all file names foreach ( $image_files as $file ) { // iterate files if ( is_file( $file ) ) { unlink( $file ); } // delete file } //Delete tables $wpdb->query( "DROP TABLE IF EXISTS $posts_table_name" ); $wpdb->query( "DROP TABLE IF EXISTS $feeds_posts_table_name" ); $locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $wpdb->query( "DROP TABLE IF EXISTS $locator_table_name" ); $table_name = $wpdb->prefix . 'options'; $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%') " ); delete_option( 'sbi_hashtag_ids' ); delete_option( 'sb_instagram_errors' ); delete_option( 'sbi_usage_tracking_config' ); delete_option( 'sbi_usage_tracking' ); delete_option( 'sbi_oembed_token' ); delete_option( 'sbi_top_api_calls' ); delete_option( 'sbi_rating_notice' ); delete_option( 'sbi_refresh_report' ); delete_option( 'sbi_welcome_seen' ); delete_option( 'sbi_notifications' ); delete_option( 'sbi_newuser_notifications' ); global $wp_roles; $wp_roles->remove_cap( 'administrator', 'manage_instagram_feed_options' ); wp_clear_scheduled_hook( 'sbi_feed_update' ); wp_clear_scheduled_hook( 'sbi_usage_tracking_cron' ); } /** * Query to Get Single source * * @param array $source_id * * @since 6.0.8 */ public static function get_source_by_account_id( $source_id ) { global $wpdb; $sources_table_name = $wpdb->prefix . 'sbi_sources'; $sql = $wpdb->prepare( "SELECT * FROM $sources_table_name WHERE account_id = %s; ", $source_id ); return $wpdb->get_row( $sql, ARRAY_A ); } } inc/Builder/Controls/SB_Hidden_Control.php000064400000001265150515074560014512 0ustar00
{{genericText.reset}}
{{toggle.label}} Pro
{{genericText.clear.replace(/ /g," ")}}
{{control.fieldPrefix.replace(/ /g," ")}}
{{control.fieldSuffix.replace(/ /g," ")}}
{{control.toggle.label}}
get_control_sources_output($controlEditingTypeModel); $this->get_control_shoppable_disabled_output($controlEditingTypeModel); $this->get_control_shoppable_enabled_output($controlEditingTypeModel); $this->get_control_shoppable_selected_post_output($controlEditingTypeModel); $this->get_control_moderation_mode_output($controlEditingTypeModel); } /** * Shoppable Feed Disabled Output Control * * * @since 4.0 * @access public * * @return HTML */ public function get_control_shoppable_disabled_output($controlEditingTypeModel){ ?>
{{control.switcher.label}}
{{genericText.moderationMode}}
{{moderationItem.label}}
{{moderationItem.description}}
{{genericText.moderationModeEnterPostId}}
'', 'type' => '', 'modelname' => '', 'layout' => 'full', 'reverse' => 'false', 'default' => '', 'seperator' => 'none', 'heading' => '', 'description' => '', 'tooltip' => '', ]; } /** * Control Output * * * @since 4.0 * @access public * * @return HTML */ public function get_control_output($controlEditingTypeModel){} /** * Getting Editing Control Type * * * @since 1.0.0 * @access public * * @return String */ public function get_control_edit_type($editingType){ switch ($editingType) { case 'settings': return 'customizerFeedData.settings'; break; } } /** * Get Control HTML. * * * @since 4.0 * @access public * * @return HTML */ public function print_control_wrapper($editingType){ $control_type = $this->get_type(); $controlEditingTypeModel = $this->get_control_edit_type($editingType); ?>
PRO
get_control_output($controlEditingTypeModel); ?>
{{control.fieldPrefix.replace(/ /g," ")}}
{{control.fieldSuffix.replace(/ /g," ")}}
{{genericText.name}}
{{genericText.edit}}
{{control.label}}
{{toggle.label}}
{{control.label}}
{{control.label}}
{{genericText.reset}}
array(12) { ["access_token"]=> string(177) "2VuX2HJb9MhA743QVp8GxZAxQZDZD" ["user_id"]=> string(17) "438429" ["username"]=> string(14) "egel" ["is_valid"]=> bool(true) ["last_checked"]=> int(1627935580) ["type"]=> string(8) "business" ["account_type"]=> string(8) "business" ["profile_picture"]=> string(308) "https://scontent.ffcm1-1.fna.fbcdn.net/v/t51.2885-15/11337206_1687352168145969_640230547_a.jpg?_nc_cat=100&ccb=1-3&_nc_sid=86c713&_nc_ohc=jwEvCq4EZ4EAX9CG3Wc&_nc_oc=AQm6GtCuqAmo9vexkGd0lk2HV9cB1R7UzXhdufRwLnSoL_QSGKgZXgoX7G4sCS3P5sw&_nc_ht=scontent.ffcm1-1.fna&oh=82ec797eaa624bd02fbdeef335a3f77f&oe=610DEE95" ["use_tagged"]=> string(1) "1" ["name"]=> string(57) "{"jsonencoded":"Example \ud83c\udfd4\ud83d\udc1f"}" ["page_access_token"]=> string(186) "V6BuEgJN9vCJzZBE3AGsZBITmXj57" ["local_avatar"]=> bool(false) } */ namespace InstagramFeed\Builder; use function DI\value; use InstagramFeed\Helpers\Util; class SBI_Source { const BATCH_SIZE = 10; /** * AJAX hooks for various feed data related functionality * * @since 6.0 */ public static function hooks() { add_action( 'wp_ajax_sbi_source_builder_update', array( 'InstagramFeed\Builder\SBI_Source', 'builder_update' ) ); add_action( 'wp_ajax_sbi_source_builder_update_multiple', array( 'InstagramFeed\Builder\SBI_Source', 'builder_update_multiple' ) ); add_action( 'wp_ajax_sbi_source_get_page', array( 'InstagramFeed\Builder\SBI_Source', 'get_page' ) ); add_action( 'admin_init', array( 'InstagramFeed\Builder\SBI_Source', 'batch_process_legacy_source_queue' ) ); } /** * Used in an AJAX call to update sources based on selections or * input from a user. Makes an API request to add additiona info * about the connected source. * * @since 6.0 */ public static function builder_update() { if ( ! check_ajax_referer( 'sbi-admin', 'nonce', false ) && ! check_ajax_referer( 'sbi-admin', 'nonce', false ) ) { wp_send_json_error(); } if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $source_data = array( 'access_token' => sanitize_text_field( $_POST['access_token'] ), 'id' => sanitize_text_field( $_POST['id'] ), 'type' => sanitize_text_field( $_POST['type'] ), 'username' => isset( $_POST['username'] ) ? sanitize_text_field( $_POST['username'] ) : '', ); $return = sbi_connect_new_account( $source_data['access_token'], $source_data['id'] ); if ( empty( $return ) ) { $return = array( 'error' => '
' . esc_html__( 'Something went wrong. Please make sure the ID and access token are correct.', 'instagram-feed' ) . '
' . '' . '
', ); } if ( empty( $return['error'] ) ) { wp_send_json_success( SBI_Feed_Builder::get_source_list() ); } wp_send_json_error( array( 'message' => $return['error'] ) ); } /** * Add our update a source from raw API data. * * @param $source_data * * @return string */ public static function process_connecting_source_data( $source_data ) { $connected_account = array( 'id' => $source_data['id'], 'user_id' => $source_data['id'], 'type' => $source_data['type'], 'account_type' => $source_data['type'], 'username' => $source_data['username'], 'access_token' => $source_data['access_token'], 'privilege' => $source_data['privilege'], ); $single_source = self::update_single_source( $connected_account, false ); if ( ! empty( $single_source['error'] ) ) { $message = ! empty( $single_source['error']['error']['message'] ) ? esc_html( $single_source['error']['error']['message'] ) : ''; $code = ! empty( $single_source['error']['error']['code'] ) ? esc_html( $single_source['error']['error']['code'] ) : ''; if ( isset( $single_source['error']['response'] ) && is_wp_error( $single_source['error']['response'] ) ) { $response = $single_source['error']['response']; $message = sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $single_source['error']['url'] ); if ( isset( $response ) && isset( $response->errors ) ) { foreach ( $response->errors as $key => $item ) { $code = $key; $message .= $item[0]; } } } $message .= ' ' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; $return_html = '
'; $return_html .= ''; $return_html .= ''; $return_html .= ''; $return_html .= '' . sprintf( __( 'Connection Error: %s ', 'instagram-feed' ), $code ) . '
' . $message . '
'; $return = array( 'success' => false, 'message' => $return_html, ); return sbi_json_encode( $return ); } else { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->remove_error( 'connection' ); } $manager = new \SB_Instagram_Data_Manager(); $manager->update_last_used(); return sbi_json_encode( SBI_Feed_Builder::get_source_list() ); } /** * Used in an AJAX call to update Multiple sources based on selections or * input from a user. Makes an API request to add additiona info * about the connected source. * * @since 6.0 */ public static function builder_update_multiple() { if ( ! check_ajax_referer( 'sbi-admin', 'nonce', false ) && ! check_ajax_referer( 'sbi-admin', 'nonce', false ) ) { wp_send_json_error(); } if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } if ( isset( $_POST['sourcesList'] ) && ! empty( $_POST['sourcesList'] ) && is_array( $_POST['sourcesList'] ) ) { foreach ( $_POST['sourcesList'] as $single_source ) : $source_data = array( 'access_token' => sanitize_text_field( $single_source['access_token'] ), 'id' => sanitize_text_field( $single_source['id'] ), 'type' => sanitize_text_field( $single_source['type'] ), 'username' => isset( $single_source['username'] ) ? sanitize_text_field( $single_source['username'] ) : '', ); if ( $single_source['type'] === 'business' ) { $source_data['privilege'] = 'tagged'; } if ( ! empty( $single_source['name'] ) ) { $source_data['name'] = sanitize_text_field( $single_source['name'] ); } self::process_connecting_source_data( $source_data ); endforeach; } echo sbi_json_encode( SBI_Feed_Builder::get_source_list() ); wp_die(); } /** * Get a list of sources with a limit and offset like a page * * @since 6.0 */ public static function get_page() { if ( ! check_ajax_referer( 'sbi-admin', 'nonce', false ) && ! check_ajax_referer( 'sbi-admin', 'nonce', false ) ) { wp_send_json_error(); } if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } $args = array( 'page' => $_POST['page'] ); $source_data = SBI_Db::source_query( $args ); echo sbi_json_encode( $source_data ); wp_die(); } /** * Connection URLs are based on the website connecting accounts so that is * configured here and returned * * @param bool $is_settings * * @return array * * @since 6.0 */ public static function get_connection_urls( $is_settings = false ) { $urls = array(); $admin_url_state = $is_settings ? admin_url( 'admin.php?page=sbi-settings' ) : admin_url( 'admin.php?page=sbi-feed-builder' ); $nonce = wp_create_nonce( 'sbi_con' ); //If the admin_url isn't returned correctly then use a fallback if ( $admin_url_state === '/wp-admin/admin.php?page=sbi-feed-builder' || $admin_url_state === '/wp-admin/admin.php?page=sbi-feed-builder&tab=configuration' ) { $admin_url_state = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; } $admin_email = get_option( 'admin_email', '' ); if ( is_user_logged_in() ) { $current_user = wp_get_current_user(); $user_email = $current_user->user_email; } $user_email = isset( $user_email ) ? $user_email : $admin_email; $urls['personal'] ='https://connect.smashballoon.com/auth/ig/?wordpress_user=' . sanitize_email( $user_email ) . '&v=free&vn=' . SBIVER . '&sbi_con=' . $nonce . '&state='; $urls['business'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=' . sanitize_email( $user_email ) . '&v=free&vn=' . SBIVER . '&sbi_con=' . $nonce . '&state='; $urls['stateURL'] = $admin_url_state; return $urls; } /** * Used as a listener for the account connection process. If * data is returned from the account connection processed it's used * to generate the list of possible sources to chose from. * * @return array|bool * * @since 6.0 */ public static function maybe_source_connection_data() { $nonce = ! empty( $_GET['sbi_con'] ) ? sanitize_key( $_GET['sbi_con'] ) : ''; if ( ! wp_verify_nonce( $nonce, 'sbi_con' ) ) { return false; } if ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_graph_api'] ) ) { $return = self::retrieve_available_business_accounts(); return $return; } elseif ( isset( $_GET['sbi_access_token'] ) && isset( $_GET['sbi_account_type'] ) ) { $return = self::retrieve_available_personal_accounts(); return $return; } return false; } /** * Uses the Instagram Basic Display API to get available personal * accounts * * @return array|bool * * @since 6.0 */ public static function retrieve_available_personal_accounts() { $encryption = new \SB_Instagram_Data_Encryption(); $return = array( 'type' => 'personal', 'unconnectedAccounts' => array(), 'matchingExistingAccounts' => array(), 'didQuickUpdate' => false, ); $access_token = sanitize_text_field( $_GET['sbi_access_token'] ); if ( empty( $access_token ) ) { return array(); } $user_id = sanitize_text_field( $_GET['sbi_id'] ); $user_name = sanitize_text_field( $_GET['sbi_username'] ); $expires_in = (int) $_GET['sbi_expires_in']; $expires_timestamp = time() + $expires_in; $source_data = array( 'access_token' => $access_token, 'id' => $user_id, 'user_id' => $user_id, 'type' => 'basic', 'username' => $user_name, 'privilege' => '', 'expires' => date( 'Y-m-d H:i:s', $expires_timestamp ), ); $connection = new \SB_Instagram_API_Connect( $source_data, 'header', array() ); $connection->connect(); $header_details = '{}'; $source_data['error'] = ''; if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $header_details_array = $connection->get_data(); $header_details_array = self::merge_account_details( $header_details_array, $source_data ); $source_data['username'] = $header_details_array['username']; $header_details = sbi_json_encode( $header_details_array ); } else { $source_data['error'] = $connection; if ( $connection->is_wp_error() ) { $page_error = $connection->get_wp_error(); if ( ! empty( $page_error ) && isset( $page_error['response']->errors ) ) { $error_message = ''; foreach ( $page_error['response']->errors as $key => $item ) { $error_message .= $key . ': ' . $item[0] . ' '; } return array( 'error' => array( 'code' => 'HTTP Request', 'message' => $error_message, 'details' => $error_message, ), ); } } else { $error = $connection->get_data(); return array( 'error' => array( 'code' => $error['error']['code'], 'message' => $error['error']['message'], 'details' => $error['error']['message'], ), ); } } $source_data['info'] = $header_details; $return['unconnectedAccounts'][] = $source_data; $args = array( 'id' => $user_id, ); $results = SBI_Db::source_query( $args ); $already_connected_as_business_account = ( isset( $results[0] ) && $results[0]['account_type'] === 'business' ); $matches_existing_personal = ( isset( $results[0] ) && $results[0]['account_type'] !== 'business' ); if ( $already_connected_as_business_account ) { $return['matchingExistingAccounts'] = $results[0]; $instagram_account_data = json_decode( $encryption->decrypt( $results[0]['info'] ), true ); $return['matchingExistingAccounts']['avatar'] = isset( $instagram_account_data['profile_picture_url'] ) ? $instagram_account_data['profile_picture_url'] : false; $return['notice'] = __( 'The Instagram account you are logged into is already connected as a "business" account. Remove the business account if you\'d like to connect as a basic account instead (not recommended).', 'instagram-feed' ); } elseif ( $matches_existing_personal ) { $return['matchingExistingAccounts'] = $results[0]; SBI_Db::delete_source( $results[0]['id'] ); self::update_or_insert( $source_data ); $return['notice'] = ''; $return['didQuickUpdate'] = true; } else { self::update_or_insert( $source_data ); $return['didQuickUpdate'] = true; } return $return; } /** * Uses the Facebook API to retrieve a list of business accounts * * @return array|bool * * @since 6.0 */ public static function retrieve_available_business_accounts() { $return = array( 'type' => 'business', 'unconnectedAccounts' => array(), 'matchingExistingAccounts' => array(), 'didQuickUpdate' => false, ); $access_token = sbi_maybe_clean( urldecode( $_GET['sbi_access_token'] ) ); if ( empty( $access_token ) ) { return array(); } $url = 'https://graph.facebook.com/me/accounts?fields=instagram_business_account,access_token&limit=500&access_token=' . $access_token; $args = array( 'timeout' => 60, ); $result = wp_remote_get( $url, $args ); $pages_data = '{}'; if ( ! is_wp_error( $result ) ) { $pages_data = $result['body']; } else { $page_error = $result; } if ( isset( $page_error ) && isset( $page_error->errors ) ) { $error_message = ''; foreach ( $page_error->errors as $key => $item ) { $error_message .= $key . ': ' . $item[0] . ' '; } return array( 'error' => array( 'code' => 'HTTP Request', 'message' => __( 'Your server could not complete a remote request to Facebook\'s API. Your host may be blocking access or there may be a problem with your server.', 'instagram-feed' ), 'details' => $error_message, ), ); } $pages_data_arr = json_decode( $pages_data, true ); if ( empty( $pages_data_arr['data'] ) ) { return array( 'error' => array( 'code' => 'No Accounts Found', 'message' => __( 'Couldn\'t find Business Profile', 'instagram-feed' ), 'details' => sprintf( __( 'Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile.', 'instagram-feed' ), '', '' ), ), ); } $user_url = 'https://graph.facebook.com/me?fields=name,id,picture&access_token=' . $access_token; $args = array( 'timeout' => 60, ); $result = wp_remote_get( $user_url, $args ); if ( ! is_wp_error( $result ) ) { $user_data = $result['body']; $user_data_arr = json_decode( $user_data, true ); $return['user'] = $user_data_arr; } $return['numFound'] = count( $pages_data_arr['data'] ); foreach ( $pages_data_arr['data'] as $page_data ) { if ( isset( $page_data['instagram_business_account'] ) ) { $instagram_business_id = $page_data['instagram_business_account']['id']; $page_access_token = isset( $page_data['access_token'] ) ? $page_data['access_token'] : ''; $instagram_account_url = 'https://graph.facebook.com/' . $instagram_business_id . '?fields=name,username,profile_picture_url&access_token=' . $access_token; $args = array( 'timeout' => 60, ); $result = wp_remote_get( $instagram_account_url, $args ); if ( ! is_wp_error( $result ) ) { $instagram_account_info = $result['body']; $instagram_account_data = json_decode( $instagram_account_info, true ); $instagram_biz_img = isset( $instagram_account_data['profile_picture_url'] ) ? $instagram_account_data['profile_picture_url'] : false; $source_data = array( 'access_token' => $access_token, 'id' => $instagram_business_id, 'user_id' => $instagram_business_id, 'type' => 'business', 'username' => $instagram_account_data['username'], 'avatar' => $instagram_biz_img, 'privilege' => 'tagged', ); $source_data['info'] = sbi_json_encode( $instagram_account_data ); $return['unconnectedAccounts'][] = $source_data; $args = array( 'id' => $instagram_business_id, ); $results = SBI_Db::source_query( $args ); $already_connected_as_business_account = ( isset( $results[0] ) && $results[0]['account_type'] === 'business' ); $matches_existing_personal = ( isset( $results[0] ) && $results[0]['account_type'] !== 'business' ); if ( $already_connected_as_business_account ) { SBI_Db::delete_source( $results[0]['id'] ); self::update_or_insert( $source_data ); } elseif ( $matches_existing_personal && $return['numFound'] === 1 ) { $return['didQuickUpdate'] = true; SBI_Db::delete_source( $results[0]['id'] ); self::update_or_insert( $source_data ); } } else { $page_error = $result; } } } if ( empty( $return['unconnectedAccounts'] ) ) { return array( 'error' => array( 'code' => 'No Accounts Found', 'message' => __( 'Couldn\'t find Business Profile', 'instagram-feed' ), 'details' => sprintf( __( 'Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile. If you are, in fact, logged-in to the correct account please make sure you have Instagram accounts connected with your Facebook account by following %3$sthis FAQ%4$s', 'instagram-feed' ), '', '', '', '' ), ), ); } return $return; } /** * Used to update or insert connected accounts (sources) * * @param array $source_data * * @return bool * * @since 6.0 */ public static function update_or_insert( $source_data ) { if ( ! isset( $source_data['id'] ) ) { return false; } if ( isset( $source_data['info'] ) ) { // data from an API request related to the source is saved as a JSON string if ( is_object( $source_data['info'] ) || is_array( $source_data['info'] ) ) { $source_data['info'] = sbi_json_encode( $source_data['info'] ); } } if ( self::exists_in_database( $source_data ) ) { $source_data['last_updated'] = date( 'Y-m-d H:i:s' ); self::update( $source_data, false ); } else { if ( ! isset( $source_data['access_token'] ) ) { return false; } self::insert( $source_data ); } return true; } /** * Whether or not the source exists in the database * * @param array $args * * @return bool * * @since 6.0 */ public static function exists_in_database( $args ) { $results = SBI_Db::source_query( $args ); return isset( $results[0] ); } /** * Add a new source as a row in the sbi_sources table * * @param array $source_data * * @return false|int * * @since 6.0 */ public static function insert( $source_data ) { if ( isset( $source_data['name'] ) ) { $source_data['username'] = $source_data['name']; } $data = $source_data; return SBI_Db::source_insert( $data ); } /** * Update info in rows that match the source data * * @param array $source_data * * @return false|int * * @since 6.0 */ public static function update( $source_data, $where_privilige = true ) { $where = array( 'id' => $source_data['id'] ); unset( $source_data['id'] ); if ( $where_privilige && isset( $source_data['privilege'] ) ) { $where['privilege'] = $source_data['privilege']; } // usernames are more common in the other plugins so // that is the name of the column that is used as the // page or group "name" data if ( isset( $source_data['name'] ) ) { $source_data['username'] = $source_data['name']; } $data = $source_data; return SBI_Db::source_update( $data, $where ); } /** * Creates a queue of connected accounts that need to be added to * the sources table * * @since 6.0 */ public static function set_legacy_source_queue() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $options = get_option( 'sb_instagram_settings', array() ); $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array(); $sbi_statuses_option['legacy_source_queue'] = array_chunk( array_keys( $connected_accounts ), self::BATCH_SIZE ); update_option( 'sbi_statuses', $sbi_statuses_option ); return $sbi_statuses_option['legacy_source_queue']; } /** * Whether or not there are still sources in the queue and * this isn't disabled * * @return bool * * @since 6.0 */ public static function should_do_source_updates() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $should_do_source_updates = isset( $sbi_statuses_option['legacy_source_queue'] ) ? ! empty( $sbi_statuses_option['legacy_source_queue'] ) : false; return apply_filters( 'should_do_source_updates', $should_do_source_updates ); } /** * Processes one set of connected accounts * * @since 6.0 */ public static function batch_process_legacy_source_queue() { if ( ! self::should_do_source_updates() ) { return; } $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $batch = array_shift( $sbi_statuses_option['legacy_source_queue'] ); update_option( 'sbi_statuses', $sbi_statuses_option ); // updated early just in case there is a fatal error if ( empty( $batch ) ) { return; } $options = get_option( 'sb_instagram_settings', array() ); $connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array(); foreach ( $batch as $account_key ) { $connected_account = isset( $connected_accounts[ $account_key ] ) ? $connected_accounts[ $account_key ] : false; if ( $connected_account ) { self::update_single_source( $connected_account ); } } return $sbi_statuses_option['legacy_source_queue']; } /** * Transfer data from a connected account to the sources table * after it's been validated with an API call * * @param array $connected_account * @param bool $connect_if_error * * @return array * * @since 6.0 */ public static function update_single_source( $connected_account, $connect_if_error = true ) { $account_type = isset( $connected_account['account_type'] ) ? $connected_account['account_type'] : 'business'; $connection = new \SB_Instagram_API_Connect( $connected_account, 'header', array() ); $connection->connect(); if ( isset( $connected_account['privilege'] ) && $connected_account['privilege'] === 'tagged' ) { $connected_account['use_tagged'] = true; } $source_data = array( 'access_token' => $connected_account['access_token'], 'id' => $connected_account['user_id'], 'type' => $account_type, 'username' => $connected_account['username'], 'privilege' => ! empty( $connected_account['use_tagged'] ) ? 'tagged' : '', ); if ( ! empty( $connected_account['expires_timestamp'] ) ) { $source_data['expires'] = date( 'Y-m-d H:i:s', $connected_account['expires_timestamp'] ); } if ( isset( $connected_account['local_avatar'] ) && $connected_account['local_avatar'] ) { \SB_Instagram_Connected_Account::update_local_avatar_status( $connected_account['username'], true ); } $header_details = '{}'; $source_data['error'] = ''; if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) { $header_array = $connection->get_data(); $header_array = self::merge_account_details( $header_array, $connected_account ); $cdn_avatar_url = \SB_Instagram_Parse::get_avatar( $header_array, array(), true ); if ( ! empty( $cdn_avatar_url ) ) { $created = \SB_Instagram_Connected_Account::create_local_avatar( $header_array['username'], $cdn_avatar_url ); \SB_Instagram_Connected_Account::update_local_avatar_status( $header_array['username'], $created ); if($created){ $header_array['local_avatar_url'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $header_array['username'] ); $header_array['local_avatar'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $header_array['username'] ); } } else { \SB_Instagram_Connected_Account::delete_local_avatar( $header_array['username'] ); $header_array['local_avatar'] = false; } $source_data['username'] = $header_array['username']; $header_details = sbi_json_encode( $header_array ); $source_data['local_avatar'] = $header_array['local_avatar']; $source_data['local_avatar_url'] = $header_array['local_avatar']; } else { $source_data['error'] = $connection; if ( $connection->is_wp_error() ) { $source_data['error'] = $connection->get_wp_error(); } else { $source_data['error'] = $connection->get_data(); } } $source_data['info'] = $header_details; if ( ! empty( $connected_account['private'] ) ) { $source_data['info']['private'] = $connected_account['private']; } if ( empty( $source_data['error'] ) || $connect_if_error ) { self::update_or_insert( $source_data ); } $source_data['record_id'] = 0; $source_data['account_id'] = $connected_account['user_id']; $source_data['account_type'] = $account_type; return $source_data; } /** * Creates a source from the access token and * source ID saved in 3.x settings * * @since 6.0 */ public static function update_source_from_legacy_settings() { // not needed } public static function merge_account_details( $header_details_array, $connected_account ) { $header_details_array['local_avatar'] = ! empty( $connected_account['local_avatar'] ); $header_details_array['name'] = ! empty( $connected_account['name'] ) ? $connected_account['name'] : '{}'; $header_details_array['page_access_token'] = ! empty( $connected_account['page_access_token'] ) ? $connected_account['page_access_token'] : ''; return $header_details_array; } /** * If the plugin is still updating legacy sources this function * can be used to udpate a single source if needed before * the update is done. * * @param string $slug_or_id * * @return array|bool */ public static function maybe_one_off_connected_account_update( $slug_or_id ) { if ( ! self::should_do_source_updates() ) { return false; } $connected_accounts = (array) json_decode( stripcslashes( get_option( 'sbi_connected_accounts' ) ), true ); $connected_account = isset( $connected_accounts[ $slug_or_id ] ) ? $connected_accounts[ $slug_or_id ] : false; if ( $connected_account ) { return self::update_single_source( $connected_account ); } return false; } /** * Clears the "error" column in the sbi_sources table for a specific * account * * @param string $account_id * * @return bool * * @since 6.0 */ public static function clear_error( $account_id ) { $source_data = array( 'id' => $account_id, 'error' => '', ); return self::update_or_insert( $source_data ); } /** * Adds an error to the error table by account ID * * @param string $account_id * @param string|object|array $error * * @return bool * * @since 6.0 */ public static function add_error( $account_id, $error ) { $source_data = array( 'id' => $account_id, 'error' => is_string( $error ) ? $error : sbi_json_encode( $error ), ); return self::update_or_insert( $source_data ); } /** * Uses query results from the sbi_sources table to convert them * into connected account data and return them as a connected account * array as would be used in versions 5.x and below * * @param array $source_data * * @return array * * @since 6.0 */ public static function convert_sources_to_connected_accounts( $source_data ) { $encryption = new \SB_Instagram_Data_Encryption(); $connected_accounts = array(); foreach ( $source_data as $source_datum ) { $info = ! empty( $source_datum['info'] ) ? json_decode( $encryption->decrypt( $source_datum['info'] ), true ) : array(); $settings = array( 'gdpr' => 'no' ); $avatar = \SB_Instagram_Parse::get_avatar( $info, $settings, true ); $connected_account = array( 'id' => $source_datum['account_id'], 'user_id' => $source_datum['account_id'], 'type' => $source_datum['account_type'], 'account_type' => $source_datum['account_type'], 'username' => $source_datum['username'], 'access_token' => sbi_maybe_clean( $source_datum['access_token'] ), 'privilege' => $source_datum['privilege'], 'expires_timestamp' => Util::get_valid_timestamp( $source_datum['expires'] ), 'is_valid' => empty( $source_datum['error'] ), 'profile_picture' => $avatar, 'last_checked' => isset( $source_datum['last_updated'] ) ? strtotime( $source_datum['last_updated'] ) : time(), ); if ( ! empty( $info['private'] ) ) { $connected_account['private'] = $info['private']; } if ( ! empty( $info['biography'] ) ) { $connected_account['bio'] = $info['biography']; } $connected_account['local_avatar_url'] = \SB_Instagram_Connected_Account::maybe_local_avatar( $source_datum['username'], $avatar ); $connected_accounts[ $source_datum['account_id'] ] = $connected_account; } return $connected_accounts; } /** * Returns a batch of accounts that have expiring access tokens * * @return array|bool * * @since 6.0 */ public static function get_expiring() { $args = array( 'expiring' => true ); $results = SBI_Db::source_query( $args ); return $results; } /** * Updates Personal Account Bio * * @return array|bool * * @since 6.0.8 */ public static function update_personal_account_bio( $account_id, $bio ) { $source = SBI_Db::get_source_by_account_id( $account_id ); if ( isset( $source['info'] ) ) { $encryption = new \SB_Instagram_Data_Encryption(); $info = json_decode( $encryption->maybe_decrypt( $source['info'] ), true ); $info = array( 'biography' => $bio ) + $info; $to_update = array(); $to_update['info'] = json_encode( $info ); SBI_Db::source_update( $to_update, array( 'id' => $account_id ) ); } } } inc/Builder/SBI_Feed_Builder.php000064400002172236150515074560012447 0ustar00init(); } /** * Init the Builder. * * @since 6.0 */ function init() { if ( is_admin() ) { add_action( 'admin_menu', array( $this, 'register_menu' ) ); // add ajax listeners SBI_Feed_Saver_Manager::hooks(); SBI_Source::hooks(); self::hooks(); } } /** * Mostly AJAX related hooks * * @since 6.0 */ public static function hooks() { add_action( 'wp_ajax_sbi_dismiss_onboarding', array( 'InstagramFeed\Builder\SBI_Feed_Builder', 'after_dismiss_onboarding' ) ); add_action( 'wp_ajax_sbi_other_plugins_modal', array( 'InstagramFeed\Builder\SBI_Feed_Builder', 'sb_other_plugins_modal' ) ); } /** * Register Menu. * * @since 6.0 */ function register_menu() { $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); $feed_builder = add_submenu_page( 'sb-instagram-feed', __( 'All Feeds', 'instagram-feed' ), __( 'All Feeds', 'instagram-feed' ), $cap, 'sbi-feed-builder', array( $this, 'feed_builder' ), 0 ); add_action( 'load-' . $feed_builder, array( $this, 'builder_enqueue_admin_scripts' ) ); } /** * Enqueue Builder CSS & Script. * * Loads only for builder pages * * @since 6.0 */ public function builder_enqueue_admin_scripts() { if ( get_current_screen() ) : $screen = get_current_screen(); if ( strpos( $screen->id, 'sbi-feed-builder' ) !== false || strpos( $screen->id, 'sbi-setup' ) !== false ) : $installed_plugins = get_plugins(); $newly_retrieved_source_connection_data = SBI_Source::maybe_source_connection_data(); $license_key = get_option( 'sbi_license_key', '' ); $upgrade_url = 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=lite-upgrade-bar'; $active_extensions = array( // Fake 'feedLayout' => false, 'headerLayout' => false, 'postStyling' => false, 'lightbox' => false, 'filtermoderation' => false, 'shoppablefeed' => false, ); $sbi_builder = array( 'ajax_handler' => admin_url( 'admin-ajax.php' ), 'pluginType' => 'free', 'licenseType' => sbi_is_pro_version() ? 'pro' : 'free', 'isSetupPage' => strpos( $screen->id, 'sbi-setup' ) !== false ? 'true' : 'false', 'builderUrl' => admin_url( 'admin.php?page=sbi-feed-builder' ), 'setUpUrl' => admin_url( 'admin.php?page=sbi-setup' ), 'upgradeUrl' => $upgrade_url, 'activeExtensions' => $active_extensions, 'pluginUrl' => trailingslashit( SBI_PLUGIN_URL ), 'nonce' => wp_create_nonce( 'sbi-admin' ), 'admin_nonce' => wp_create_nonce( 'sbi_admin_nonce' ), 'adminPostURL' => admin_url( 'post.php' ), 'widgetsPageURL' => admin_url( 'widgets.php' ), 'themeSupportsWidgets' => current_theme_supports( 'widgets' ), 'supportPageUrl' => admin_url( 'admin.php?page=sbi-support' ), 'genericText' => self::get_generic_text(), 'welcomeScreen' => array( 'mainHeading' => __( 'All Feeds', 'instagram-feed' ), 'createFeed' => __( 'Create your Feed', 'instagram-feed' ), 'createFeedDescription' => __( 'Connect your Instagram account and choose a feed type', 'instagram-feed' ), 'customizeFeed' => __( 'Customize your feed type', 'instagram-feed' ), 'customizeFeedDescription' => __( 'Choose layouts, color schemes, styles and more', 'instagram-feed' ), 'embedFeed' => __( 'Embed your feed', 'instagram-feed' ), 'embedFeedDescription' => __( 'Easily add the feed anywhere on your website', 'instagram-feed' ), 'customizeImgPath' => SBI_BUILDER_URL . 'assets/img/welcome-1.png', 'embedImgPath' => SBI_BUILDER_URL . 'assets/img/welcome-2.png', ), 'pluginsInfo' => array( 'social_wall' => array( 'installed' => isset( $installed_plugins['social-wall/social-wall.php'] ) ? true : false, 'activated' => is_plugin_active( 'social-wall/social-wall.php' ), 'settingsPage' => admin_url( 'admin.php?page=sbsw' ), ) ), 'allFeedsScreen' => array( 'mainHeading' => __( 'All Feeds', 'instagram-feed' ), 'columns' => array( 'nameText' => __( 'Name', 'instagram-feed' ), 'shortcodeText' => __( 'Shortcode', 'instagram-feed' ), 'instancesText' => __( 'Instances', 'instagram-feed' ), 'actionsText' => __( 'Actions', 'instagram-feed' ), ), 'bulkActions' => __( 'Bulk Actions', 'instagram-feed' ), 'legacyFeeds' => array( 'heading' => __( 'Legacy Feeds', 'instagram-feed' ), 'toolTip' => __( 'What are Legacy Feeds?', 'instagram-feed' ), 'toolTipExpanded' => array( __( 'Legacy feeds are older feeds from before the version 6 update. You can edit settings for these feeds by using the "Settings" button to the right. These settings will apply to all legacy feeds, just like the settings before version 6, and work in the same way that they used to.', 'instagram-feed' ), __( 'You can also create a new feed, which will now have it\'s own individual settings. Modifying settings for new feeds will not affect other feeds.', 'instagram-feed' ), ), 'toolTipExpandedAction' => array( __( 'Legacy feeds represent shortcodes of old feeds found on your website before
the version 6 update.', 'instagram-feed' ), __( 'To edit Legacy feed settings, you will need to use the "Settings" button above
or edit their shortcode settings directly. To delete them, simply remove the
shortcode wherever it is being used on your site.', 'instagram-feed' ), ), 'show' => __( 'Show Legacy Feeds', 'instagram-feed' ), 'hide' => __( 'Hide Legacy Feeds', 'instagram-feed' ), ), 'socialWallLinks' => self::get_social_wall_links(), 'onboarding' => $this->get_onboarding_text() ), 'dialogBoxPopupScreen' => array( 'deleteSource' => array( 'heading' => __( 'Delete "#"?', 'instagram-feed' ), 'description' => __( 'This source is being used in a feed on your site. If you delete this source then new posts can no longer be retrieved for these feeds.', 'instagram-feed' ), ), 'deleteSourceCustomizer' => array( 'heading' => __( 'Delete "#"?', 'instagram-feed' ), 'description' => __( 'You are going to delete this source. To retrieve it, you will need to add it again. Are you sure you want to continue?', 'instagram-feed' ), ), 'deleteSingleFeed' => array( 'heading' => __( 'Delete "#"?', 'instagram-feed' ), 'description' => __( 'You are going to delete this feed. You will lose all the settings. Are you sure you want to continue?', 'instagram-feed' ), ), 'deleteMultipleFeeds' => array( 'heading' => __( 'Delete Feeds?', 'instagram-feed' ), 'description' => __( 'You are going to delete these feeds. You will lose all the settings. Are you sure you want to continue?', 'instagram-feed' ), ), 'backAllToFeed' => array( 'heading' => __( 'Are you Sure?', 'instagram-feed' ), 'description' => __( 'Are you sure you want to leave this page, all unsaved settings will be lost, please make sure to save before leaving.', 'instagram-feed' ), 'customButtons' => array( 'confirm' => array( 'text' => __( 'Save and Exit', 'instagram-feed' ), 'color' => 'blue', ), 'cancel' => array( 'text' => __( 'Exit without Saving', 'instagram-feed' ), 'color' => 'red', ), ), ), 'unsavedFeedSources' => array( 'heading' => __( 'You have unsaved changes', 'instagram-feed' ), 'description' => __( 'If you exit without saving, all the changes you made will be reverted.', 'instagram-feed' ), 'customButtons' => array( 'confirm' => array( 'text' => __( 'Save and Exit', 'instagram-feed' ), 'color' => 'blue' ), 'cancel' => array( 'text' => __( 'Exit without Saving', 'instagram-feed' ), 'color' => 'red' ) ) ) ), 'selectFeedTypeScreen' => array( 'mainHeading' => __( 'Create an Instagram Feed', 'instagram-feed' ), 'feedTypeHeading' => __( 'Select Feed Type', 'instagram-feed' ), 'mainDescription' => __( 'Select one or more feed types. You can add or remove them later.', 'instagram-feed' ), 'updateHeading' => __( 'Update Feed Type', 'instagram-feed' ), 'advancedHeading' => __( 'Advanced Feeds', 'instagram-feed' ), 'anotherFeedTypeHeading' => __( 'Add Another Source Type', 'instagram-feed' ), ), 'mainFooterScreen' => array( 'heading' => sprintf( __( 'Upgrade to the %1$sAll Access Bundle%2$s to get all of our Pro Plugins', 'instagram-feed' ), '', '' ), 'description' => __( 'Includes all Smash Balloon plugins for one low price: Instagram, Facebook, Twitter, YouTube, and Social Wall', 'instagram-feed' ), 'promo' => sprintf( __( '%1$sBonus%2$s Lite users get %3$s50% Off%4$s automatically applied at checkout', 'instagram-feed' ), '', '', '', '' ), ), 'embedPopupScreen' => array( 'heading' => __( 'Embed Feed', 'instagram-feed' ), 'description' => __( 'Add the unique shortcode to any page, post, or widget:', 'instagram-feed' ), 'description_2' => current_theme_supports( 'widgets' ) ? __( 'Or use the built in WordPress block or widget', 'instagram-feed' ) : __( 'Or use the built in WordPress block', 'instagram-feed' ), 'addPage' => __( 'Add to a Page', 'instagram-feed' ), 'addWidget' => __( 'Add to a Widget', 'instagram-feed' ), 'selectPage' => __( 'Select Page', 'instagram-feed' ), ), 'links' => self::get_links_with_utm(), 'pluginsInfo' => array( 'social_wall' => array( 'installed' => isset( $installed_plugins['social-wall/social-wall.php'] ) ? true : false, 'activated' => is_plugin_active( 'social-wall/social-wall.php' ), 'settingsPage' => admin_url( 'admin.php?page=sbsw' ), ) ), 'selectSourceScreen' => self::select_source_screen_text(), 'feedTypes' => $this->get_feed_types(), 'advancedFeedTypes' => $this->get_advanced_feed_types(), 'socialInfo' => $this->get_smashballoon_info(), 'svgIcons' => $this->builder_svg_icons(), 'installPluginsPopup' => $this->install_plugins_popup(), 'feeds' => self::get_feed_list(), 'itemsPerPage' => SBI_Db::RESULTS_PER_PAGE, 'feedsCount' => SBI_Db::feeds_count(), 'sources' => self::get_source_list(), 'sourceConnectionURLs' => SBI_Source::get_connection_urls(), 'legacyFeeds' => $this->get_legacy_feed_list(), 'extensionsPopup' => array( 'hashtag' => array( 'heading' => __( 'Upgrade to Pro to get Hashtag Feeds', 'instagram-feed' ), 'description' => __( 'Display posts from any public hashtag with an Instagram hashtag feed. Great for pulling in user-generated content associated with your brand, running promotional hashtag campaigns, engaging audiences at events, and more.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/hashtag?utm_campaign=instagram-free&utm_source=feed-type&utm_medium=hashtag' ) ), 'tagged' => array( 'heading' => __( 'Upgrade to Pro to get Tagged Posts Feed', 'instagram-feed' ), 'description' => __( 'Display posts that you\'ve been tagged in by other users allowing you to increase your audience\'s engagement with your Instagram account.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=feed-type&utm_medium=tagged' ) ), 'socialwall' => array( // Combine all your social media channels into one Social Wall 'heading' => '' . __( 'Combine all your social media channels into one', 'instagram-feed' ) .' '. __( 'Social Wall', 'instagram-feed' ).'', 'description' => '' . __( 'A dash of Instagram, a sprinkle of Facebook, a spoonful of Twitter, and a dollop of YouTube, all in the same feed.', 'instagram-feed' ) . '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'img' => '', 'demoUrl' => 'https://smashballoon.com/social-wall/demo/?utm_campaign=instagram-free&utm_source=feed-type&utm_medium=social-wall&utm_content=learn-more', 'buyUrl' => sprintf( 'https://smashballoon.com/social-wall/demo/?license_key=%s&upgrade=true&utm_campaign=instagram-free&utm_source=feed-type&utm_medium=social-wall&utm_content=Try Demo', $license_key ), 'bullets' => array( 'heading' => __( 'Upgrade to the All Access Bundle and get:', 'instagram-feed' ), 'content' => array( __( 'Instagram Feed Pro', 'instagram-feed' ), __( 'Custom Twitter Feeds Pro', 'instagram-feed' ), __( 'YouTube Feeds Pro', 'instagram-feed' ), __( 'Custom Facebook Feed Pro', 'instagram-feed' ), __( 'All Pro Facebook Extensions', 'instagram-feed' ), __( 'Social Wall Pro', 'instagram-feed' ), ) ), ), // Other Types 'feedLayout' => array( 'heading' => __( 'Upgrade to Pro to get Feed Layouts', 'instagram-feed' ), 'description' => __( 'Choose from one of our built-in layout options; grid, carousel, masonry, and highlight to allow you to showcase your content in any way you want.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=feed-layouts' ) ), 'headerLayout' => array( 'heading' => __( 'Get Stories, Followers and Advanced Header Options', 'instagram-feed' ), 'description' => __( 'Got stories to tell? We want to help you share them. Display Instagram stories right on your website in a pop-up lightbox to keep your users engaged and on your website for longer.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=header' ) ), 'postStyling' => array( 'heading' => __( 'Display Captions, Likes, and Comments', 'instagram-feed' ), 'description' => __( 'Upgrade to Pro to display post captions below each post and in the lightbox, which can be crawled by search engines to help boost SEO.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=posts' ) ), 'lightbox' => array( 'heading' => __( 'Upgrade to Pro to enable the popup Lightbox', 'instagram-feed' ), 'description' => __( 'Allow visitors to view your photos and videos in a beautiful full size lightbox, keeping them on your site for longer to discover more of your content.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=lightbox' ) ), 'filtermoderation' => array( 'heading' => __( 'Get Advanced Moderation and Filters with Pro', 'instagram-feed' ), 'description' => __( 'Use powerful moderation tools to easily create feeds of only specific photos, or choose specific ones to exclude. You can also easily choose to include or block specific words or phrases in your posts.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=filters' ) ), 'shoppablefeed' => array( 'heading' => __( 'Upgrade to Pro to Get Shoppable Feeds', 'instagram-feed' ), 'description' => __( 'Automatically link Instagram posts to custom URLs of your choosing by adding the URL in the caption, or manually add links to specific pages or products on your site (or other sites) in a quick and easy way.', 'instagram-feed' ), 'img' => '', 'popupContentBtn' => '
' . self::builder_svg_icons()['tag'] . __( 'Instagram Pro users get 50% OFF', 'instagram-feed' ) . '
', 'bullets' => array( 'heading' => __( 'And get much more!', 'instagram-feed' ), 'content' => array( __( 'Display Hashtag & Tagged feeds', 'instagram-feed' ), __( 'Powerful visual moderation', 'instagram-feed' ), __( 'Comments and Likes', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Multiple layout options', 'instagram-feed' ), __( 'Popup photo/video lightbox', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Shoppable feeds', 'instagram-feed' ), __( 'Pro support', 'instagram-feed' ), __( 'Post captions', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), ) ), 'buyUrl' => sprintf( 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=shoppable' ) ), ), 'personalAccountScreen' => self::personal_account_screen_text(), 'onboardingWizardContent' => \InstagramFeed\admin\SBI_Onboarding_wizard::get_onboarding_wizard_content() ); if ( $newly_retrieved_source_connection_data ) { $sbi_builder['newSourceData'] = $newly_retrieved_source_connection_data; } if ( isset( $_GET['manualsource'] ) && $_GET['manualsource'] == true ) { $sbi_builder['manualSourcePopupInit'] = true; } $maybe_feed_customizer_data = SBI_Feed_Saver_Manager::maybe_feed_customizer_data(); if ( $maybe_feed_customizer_data ) { sb_instagram_scripts_enqueue( true ); $sbi_builder['customizerFeedData'] = $maybe_feed_customizer_data; $sbi_builder['customizerSidebarBuilder'] = \InstagramFeed\Builder\Tabs\SBI_Builder_Customizer_Tab::get_customizer_tabs(); $sbi_builder['wordpressPageLists'] = $this->get_wp_pages(); $sbi_builder['instagram_feed_dismiss_lite'] = get_transient( 'instagram_feed_dismiss_lite' ); if ( ! isset( $_GET['feed_id'] ) || $_GET['feed_id'] === 'legacy' ) { $feed_id = 'legacy'; $customizer_atts = array( 'feed' => 'legacy', 'customizer' => true ); } elseif ( intval( $_GET['feed_id'] ) > 0 ) { $feed_id = intval( $_GET['feed_id'] ); $customizer_atts = array( 'feed' => $feed_id, 'customizer' => true ); } if ( ! empty( $feed_id ) ) { $settings_preview = self::add_customizer_att( $customizer_atts ); if ( $feed_id === 'legacy' ) { $preview_settings = \SB_Instagram_Settings::get_legacy_feed_settings(); $preview_settings['customizer'] = true; $sbi_builder['feedInitOutput'] = htmlspecialchars( display_instagram( $customizer_atts, $preview_settings ) ); } else { $sbi_builder['feedInitOutput'] = htmlspecialchars( display_instagram( $settings_preview, true ) ); } } // Date global $wp_locale; wp_enqueue_script( 'sbi-date_i18n', SBI_PLUGIN_URL . 'admin/builder/assets/js/date_i18n.js', null, SBIVER, true ); $monthNames = array_map( array( &$wp_locale, 'get_month' ), range( 1, 12 ) ); $monthNamesShort = array_map( array( &$wp_locale, 'get_month_abbrev' ), $monthNames ); $dayNames = array_map( array( &$wp_locale, 'get_weekday' ), range( 0, 6 ) ); $dayNamesShort = array_map( array( &$wp_locale, 'get_weekday_abbrev' ), $dayNames ); wp_localize_script( 'sbi-date_i18n', 'DATE_I18N', array( 'month_names' => $monthNames, 'month_names_short' => $monthNamesShort, 'day_names' => $dayNames, 'day_names_short' => $dayNamesShort ) ); } wp_enqueue_style( 'sbi-builder-style', SBI_PLUGIN_URL . 'admin/builder/assets/css/builder.css', false, SBIVER ); self::global_enqueue_ressources_scripts(); wp_enqueue_script( 'sbi-builder-app', SBI_PLUGIN_URL . 'admin/builder/assets/js/builder.js', null, SBIVER, true ); // Customize screens $sbi_builder['customizeScreens'] = $this->get_customize_screens_text(); wp_localize_script( 'sbi-builder-app', 'sbi_builder', $sbi_builder ); wp_enqueue_media(); endif; endif; } /** * Get WP Pages List * * @return array * * @since 6.0 */ public function get_wp_pages() { $pagesList = get_pages(); $pagesResult = array(); if ( is_array( $pagesList ) ) { foreach ( $pagesList as $page ) { array_push( $pagesResult, array( 'id' => $page->ID, 'title' => $page->post_title ) ); } } return $pagesResult; } /** * Global JS + CSS Files * * Shared JS + CSS ressources for the admin panel * * @since 6.0 */ public static function global_enqueue_ressources_scripts( $is_settings = false ) { wp_enqueue_style( 'feed-global-style', SBI_PLUGIN_URL . 'admin/builder/assets/css/global.css', false, SBIVER ); wp_enqueue_script( 'sb-vue', SBI_PLUGIN_URL . 'js/vue.min.js', null, '2.6.12', true ); wp_enqueue_script( 'feed-colorpicker-vue', SBI_PLUGIN_URL . 'admin/builder/assets/js/vue-color.min.js', null, SBIVER, true ); wp_enqueue_script( 'feed-builder-ressources', SBI_PLUGIN_URL . 'admin/builder/assets/js/ressources.js', null, SBIVER, true ); wp_enqueue_script( 'sb-dialog-box', SBI_PLUGIN_URL . 'admin/builder/assets/js/confirm-dialog.js', null, SBIVER, true ); wp_enqueue_script( 'install-plugin-popup', SBI_PLUGIN_URL . 'admin/builder/assets/js/install-plugin-popup.js', null, SBIVER, true ); wp_enqueue_script( 'sb-add-source', SBI_PLUGIN_URL . 'admin/builder/assets/js/add-source.js', null, SBIVER, true ); $newly_retrieved_source_connection_data = SBI_Source::maybe_source_connection_data(); $sbi_source = array( 'sources' => self::get_source_list(), 'sourceConnectionURLs' => SBI_Source::get_connection_urls( $is_settings ), 'nonce' => wp_create_nonce( 'sbi-admin' ), ); if ( $newly_retrieved_source_connection_data ) { $sbi_source['newSourceData'] = $newly_retrieved_source_connection_data; } if ( isset( $_GET['manualsource'] ) && $_GET['manualsource'] == true ) { $sbi_source['manualSourcePopupInit'] = true; } wp_localize_script( 'sb-add-source', 'sbi_source', $sbi_source ); wp_enqueue_script( 'sb-personal-account', SBI_PLUGIN_URL . 'admin/builder/assets/js/personal-account.js', null, SBIVER, true ); $sbi_personal_account = array( 'personalAccountScreen' => self::personal_account_screen_text(), 'nonce' => wp_create_nonce( 'sbi-admin' ), 'ajaxHandler' => admin_url( 'admin-ajax.php' ), ); wp_localize_script( 'sb-personal-account', 'sbi_personal_account', $sbi_personal_account ); } /** * Get Generic text * * @return array * * @since 6.0 */ public static function get_generic_text() { $icons = self::builder_svg_icons(); return array( 'done' => __( 'Done', 'instagram-feed' ), 'title' => __( 'Settings', 'instagram-feed' ), 'dashboard' => __( 'Dashboard', 'instagram-feed' ), 'setup' => __( 'Setup', 'instagram-feed' ), 'addNew' => __( 'Add New', 'instagram-feed' ), 'addSource' => __( 'Add Source', 'instagram-feed' ), 'addAnotherSource' => __( 'Add another Source', 'instagram-feed' ), 'addSourceType' => __( 'Add Another Source Type', 'instagram-feed' ), 'previous' => __( 'Previous', 'instagram-feed' ), 'next' => __( 'Next', 'instagram-feed' ), 'finish' => __( 'Finish', 'instagram-feed' ), 'new' => __( 'New', 'instagram-feed' ), 'update' => __( 'Update', 'instagram-feed' ), 'upgrade' => __( 'Try the Pro Demo', 'instagram-feed' ), 'settings' => __( 'Settings', 'instagram-feed' ), 'back' => __( 'Back', 'instagram-feed' ), 'backAllFeeds' => __( 'Back to all feeds', 'instagram-feed' ), 'createFeed' => __( 'Create Feed', 'instagram-feed' ), 'add' => __( 'Add', 'instagram-feed' ), 'change' => __( 'Change', 'instagram-feed' ), 'getExtention' => __( 'Get Extension', 'instagram-feed' ), 'viewDemo' => __( 'View Demo', 'instagram-feed' ), 'includes' => __( 'Includes', 'instagram-feed' ), 'photos' => __( 'Photos', 'instagram-feed' ), 'photo' => __( 'Photo', 'instagram-feed' ), 'apply' => __( 'Apply', 'instagram-feed' ), 'copy' => __( 'Copy', 'instagram-feed' ), 'edit' => __( 'Edit', 'instagram-feed' ), 'duplicate' => __( 'Duplicate', 'instagram-feed' ), 'delete' => __( 'Delete', 'instagram-feed' ), 'remove' => __( 'Remove', 'instagram-feed' ), 'removeSource' => __( 'Remove Source', 'instagram-feed' ), 'shortcode' => __( 'Shortcode', 'instagram-feed' ), 'clickViewInstances' => __( 'Click to view Instances', 'instagram-feed' ), 'usedIn' => __( 'Used in', 'instagram-feed' ), 'place' => __( 'place', 'instagram-feed' ), 'places' => __( 'places', 'instagram-feed' ), 'item' => __( 'Item', 'instagram-feed' ), 'items' => __( 'Items', 'instagram-feed' ), 'learnMore' => __( 'Learn More', 'instagram-feed' ), 'location' => __( 'Location', 'instagram-feed' ), 'page' => __( 'Page', 'instagram-feed' ), 'copiedClipboard' => __( 'Copied to Clipboard', 'instagram-feed' ), 'feedImported' => __( 'Feed imported successfully', 'instagram-feed' ), 'failedToImportFeed' => __( 'Failed to import feed', 'instagram-feed' ), 'timeline' => __( 'Timeline', 'instagram-feed' ), 'help' => __( 'Help', 'instagram-feed' ), 'admin' => __( 'Admin', 'instagram-feed' ), 'member' => __( 'Member', 'instagram-feed' ), 'reset' => __( 'Reset', 'instagram-feed' ), 'preview' => __( 'Preview', 'instagram-feed' ), 'name' => __( 'Name', 'instagram-feed' ), 'id' => __( 'ID', 'instagram-feed' ), 'token' => __( 'Token', 'instagram-feed' ), 'confirm' => __( 'Confirm', 'instagram-feed' ), 'cancel' => __( 'Cancel', 'instagram-feed' ), 'clear' => __( 'Clear', 'instagram-feed' ), 'clearFeedCache' => __( 'Clear Feed Cache', 'instagram-feed' ), 'saveSettings' => __( 'Save Changes', 'instagram-feed' ), 'feedName' => __( 'Feed Name', 'instagram-feed' ), 'shortcodeText' => __( 'Shortcode', 'instagram-feed' ), 'general' => __( 'General', 'instagram-feed' ), 'feeds' => __( 'Feeds', 'instagram-feed' ), 'translation' => __( 'Translation', 'instagram-feed' ), 'advanced' => __( 'Advanced', 'instagram-feed' ), 'error' => __( 'Error:', 'instagram-feed' ), 'errorNotice' => __( 'There was an error when trying to connect to Instagram.', 'instagram-feed' ), 'errorDirections' => '' . __( 'Directions on How to Resolve This Issue', 'instagram-feed' ) . '', 'errorSource' => __( 'Source Invalid', 'instagram-feed' ), 'errorEncryption' => __( 'Encryption Error', 'instagram-feed' ), 'invalid' => __( 'Invalid', 'instagram-feed' ), 'reconnect' => __( 'Reconnect', 'instagram-feed' ), 'feed' => __( 'feed', 'instagram-feed' ), 'sourceNotUsedYet' => __( 'Source is not used yet', 'instagram-feed' ), 'addImage' => __( 'Add Image', 'instagram-feed' ), 'businessRequired' => __( 'Business Account required', 'instagram-feed' ), 'selectedPost' => __( 'Selected Post', 'instagram-feed' ), 'productLink' => __( 'Product Link', 'instagram-feed' ), 'enterProductLink' => __( 'Add your product URL here', 'instagram-feed' ), 'editSources' => __( 'Edit Sources', 'instagram-feed' ), 'moderateFeed' => __( 'Moderate your feed', 'instagram-feed' ), 'moderateFeedSaveExit' => __( 'Save and Exit', 'instagram-feed' ), 'moderationMode' => __( 'Moderation Mode', 'instagram-feed' ), 'moderationModeEnterPostId' => __( 'Or Enter Post IDs to hide manually', 'instagram-feed' ), 'moderationModeTextareaPlaceholder' => __( 'Add words here to hide any posts containing these words', 'instagram-feed' ), 'filtersAndModeration' => __( 'Filters & Moderation', 'instagram-feed' ), 'topRated' => __( 'Top Rated', 'instagram-feed' ), 'mostRecent' => __( 'Most recent', 'instagram-feed' ), 'moderationModePreview' => __( 'Moderation Mode Preview', 'instagram-feed' ), 'exitSetup' => __( 'Exit Setup', 'instagram-feed' ), 'notification' => array( 'feedSaved' => array( 'type' => 'success', 'text' => __( 'Feed saved successfully', 'instagram-feed' ) ), 'feedSavedError' => array( 'type' => 'error', 'text' => __( 'Error saving Feed', 'instagram-feed' ) ), 'previewUpdated' => array( 'type' => 'success', 'text' => __( 'Preview updated successfully', 'instagram-feed' ) ), 'carouselLayoutUpdated' => array( 'type' => 'success', 'text' => __( 'Carousel updated successfully', 'instagram-feed' ) ), 'unkownError' => array( 'type' => 'error', 'text' => __( 'Unknown error occurred', 'instagram-feed' ) ), 'cacheCleared' => array( 'type' => 'success', 'text' => __( 'Feed cache cleared', 'instagram-feed' ) ), 'selectSourceError' => array( 'type' => 'error', 'text' => __( 'Please select a source for your feed', 'instagram-feed' ) ), 'commentCacheCleared' => array( 'type' => 'success', 'text' => __( 'Comment cache cleared', 'instagram-feed' ) ), 'personalAccountUpdated' => array( 'type' => 'success', 'text' => __( 'Personal account updated', 'instagram-feed' ) ) ), 'install' => __( 'Install', 'instagram-feed' ), 'installed' => __( 'Installed', 'instagram-feed' ), 'activate' => __( 'Activate', 'instagram-feed' ), 'installedAndActivated' => __( 'Installed & Activated', 'instagram-feed' ), 'free' => __( 'Free', 'instagram-feed' ), 'invalidLicenseKey' => __( 'Invalid license key', 'instagram-feed' ), 'licenseActivated' => __( 'License activated', 'instagram-feed' ), 'licenseDeactivated' => __( 'License Deactivated', 'instagram-feed' ), 'carouselLayoutUpdated' => array( 'type' => 'success', 'text' => __( 'Carousel Layout updated', 'instagram-feed' ) ), 'getMoreFeatures' => __( 'Get more features with Instagram Feed Pro', 'instagram-feed' ), 'liteFeedUsers' => __( 'Lite users get 50% OFF', 'instagram-feed' ), 'liteFeedUsersAutoApply' => __( 'Lite users get 50% OFF automatically applied at checkout', 'instagram-feed' ), 'tryDemo' => __( 'Try Demo', 'instagram-feed' ), 'displayImagesVideos' => __( 'Display images and videos in posts', 'instagram-feed' ), 'viewLikesShares' => __( 'View likes, shares and comments', 'instagram-feed' ), 'allFeedTypes' => __( 'All Feed Types: Photos, Albums, Events and more', 'instagram-feed' ), 'abilityToLoad' => __( 'Ability to “Load More” posts', 'instagram-feed' ), 'ctaHashtag' => __( 'Display Hashtag Feeds', 'instagram-feed' ), 'ctaLayout' => __( 'Carousel, Masonry, & Highlight layouts', 'instagram-feed' ), 'ctaPopups' => __( 'View posts in a pop-up lightbox', 'instagram-feed' ), 'ctaFilter' => __( 'Powerful post filtering and moderation', 'instagram-feed' ), 'andMuchMore' => __( 'And Much More!', 'instagram-feed' ), 'sbiFreeCTAFeatures' => array( __( 'Create shoppable feeds', 'instagram-feed' ), __( 'Combine multiple feed types', 'instagram-feed' ), __( 'Display likes, captions & comments', 'instagram-feed' ), __( 'Instagram Stories', 'instagram-feed' ), __( 'Play videos in your feed', 'instagram-feed' ), __( 'Highlight specific posts', 'instagram-feed' ), __( 'Display tagged posts', 'instagram-feed' ), __( '30 day money back guarantee', 'instagram-feed' ), __( 'Fast, friendly, and effective support', 'instagram-feed' ), ), 'ctaShowFeatures' => __( 'Show Features', 'instagram-feed' ), 'ctaHideFeatures' => __( 'Hide Features', 'instagram-feed' ), 'upgradeToPro' => __( 'Upgrade to Pro', 'instagram-feed' ), 'redirectLoading' => array( 'heading' => __( 'Redirecting to connect.smashballoon.com', 'instagram-feed' ), 'description' => __( 'You will be redirected to our app so you can connect your account in 5 seconds', 'instagram-feed' ), ), 'addAccountInfo' => __( 'Add Avatar and Bio', 'instagram-feed' ), 'updateAccountInfo' => __( 'Update Avatar and Bio', 'instagram-feed' ), 'personalAccountUpdated' => __( 'Personal account updated', 'instagram-feed' ), ); } /** * Select Source Screen Text * * @return array * * @since 4.0 */ public static function select_source_screen_text() { return array( 'mainHeading' => __( 'Select one or more sources', 'instagram-feed' ), 'description' => __( 'Sources are Instagram accounts your feed will display content from', 'instagram-feed' ), 'emptySourceDescription' => __( 'Looks like you have not added any source.
Use “Add Source” to add a new one.', 'instagram-feed' ), 'mainHashtagHeading' => __( 'Enter Public Hashtags', 'instagram-feed' ), 'hashtagDescription' => __( 'Add one or more hashtag separated by comma', 'instagram-feed' ), 'hashtagGetBy' => __( 'Fetch posts that are', 'instagram-feed' ), 'sourcesListPopup' => array( 'user' => array( 'mainHeading' => __( 'Add a source for Timeline', 'instagram-feed' ), 'description' => __( 'Select or add an account you want to display the timeline for', 'instagram-feed' ), ), 'tagged' => array( 'mainHeading' => __( 'Add a source for Mentions', 'instagram-feed' ), 'description' => __( 'Select or add an account you want to display the mentions for', 'instagram-feed' ), ) ), 'perosnalAccountToolTipTxt' => array( __( 'Due to changes in Instagram’s new API, we can no
longer get mentions for personal accounts. To
enable this for your account, you will need to convert it to
a Business account. Learn More', 'instagram-feed' ), ), 'groupsToolTip' => array( __( 'Due to Facebook limitations, it\'s not possible to display photo feeds from a Group, only a Page.', 'instagram-feed' ) ), 'updateHeading' => __( 'Update Source', 'instagram-feed' ), 'updateDescription' => __( 'Select a source from your connected Facebook Pages and Groups. Or, use "Add New" to connect a new one.', 'instagram-feed' ), 'updateFooter' => __( 'Add multiple Facebook Pages or Groups to a feed with our Multifeed extension', 'instagram-feed' ), 'noSources' => __( 'Please add a source in order to display a feed. Go to the "Settings" tab -> "Sources" section -> Click "Add New" to connect a source.', 'instagram-feed' ), 'multipleTypes' => array( 'user' => array( 'heading' => __( 'User Timeline', 'instagram-feed' ), 'icon' => 'user', 'description' => __( 'Connect an account to show posts for it.', 'instagram-feed' ), 'actionType' => 'addSource' ), 'hashtag' => array( 'heading' => __( 'Hashtag', 'instagram-feed' ), 'icon' => 'hashtag', 'description' => __( 'Add one or more hashtag separated by comma.', 'instagram-feed' ), 'businessRequired' => true, 'actionType' => 'inputHashtags' ), 'tagged' => array( 'heading' => __( 'Tagged', 'instagram-feed' ), 'icon' => 'mention', 'description' => __( 'Connect an account to show tagged posts. This does not give us any permission to manage your Instagram account.', 'instagram-feed' ), 'businessRequired' => true, 'actionType' => 'addSource' ) ), 'modal' => array( 'addNew' => __( 'Connect your Instagram Account', 'instagram-feed' ), 'selectSourceType' => __( 'Select Account Type', 'instagram-feed' ), 'connectAccount' => __( 'Connect an Instagram Account', 'instagram-feed' ), 'connectAccountDescription' => __( 'This does not give us permission to manage your Instagram account, it simply allows the plugin to see a list of them and retrieve their public content from the API.', 'instagram-feed' ), 'connect' => __( 'Connect', 'instagram-feed' ), 'enterEventToken' => __( 'Enter Events Access Token', 'instagram-feed' ), 'enterEventTokenDescription' => sprintf( __( 'Due to restrictions by Facebook, you need to create a Facebook app and then paste that app Access Token here. We have a guide to help you with just that, which you can read %1$shere%2$s', 'instagram-feed' ), '', '' ), 'alreadyHave' => __( 'Already have a API Token and Access Key for your account?', 'instagram-feed' ), 'addManuallyLink' => __( 'Add Account Manually', 'instagram-feed' ), 'selectAccount' => __( 'Select an Instagram Account', 'instagram-feed' ), 'showing' => __( 'Showing', 'instagram-feed' ), 'facebook' => __( 'Facebook', 'instagram-feed' ), 'businesses' => __( 'Businesses', 'instagram-feed' ), 'groups' => __( 'Groups', 'instagram-feed' ), 'connectedTo' => __( 'connected to', 'instagram-feed' ), 'addManually' => __( 'Add a Source Manually', 'instagram-feed' ), 'addSource' => __( 'Add Source', 'instagram-feed' ), 'sourceType' => __( 'Source Type', 'instagram-feed' ), 'accountID' => __( 'Instagram Account ID', 'instagram-feed' ), 'fAccountID' => __( 'Instagram Account ID', 'instagram-feed' ), 'eventAccessToken' => __( 'Event Access Token', 'instagram-feed' ), 'enterID' => __( 'Enter ID', 'instagram-feed' ), 'accessToken' => __( 'Instagram Access Token', 'instagram-feed' ), 'enterToken' => __( 'Enter Token', 'instagram-feed' ), 'addApp' => __( 'Add Instagram App to your group', 'instagram-feed' ), 'addAppDetails' => __( 'To get posts from your group, Instagram requires the "Smash Balloon Plugin" app to be added in your group settings. Just follow the directions here:', 'instagram-feed' ), 'addAppSteps' => array( __( 'Go to your group settings page by ', 'instagram-feed' ), sprintf( __( 'Search for "Smash Balloon" and select our app %1$s(see screenshot)%2$s', 'instagram-feed' ), '', 'Thumbnail Layout' ), __( 'Click "Add" and you are done.', 'instagram-feed' ) ), 'alreadyExists' => __( 'Account already exists', 'instagram-feed' ), 'alreadyExistsExplanation' => __( 'The Instagram account you added is already connected as a “Business” account. Would you like to replace it with a “Personal“ account? (Note: Personal accounts cannot be used to display Mentions or Hashtag feeds.)', 'instagram-feed' ), 'replaceWithPersonal' => __( 'Replace with Personal', 'instagram-feed' ), 'notAdmin' => __( 'For groups you are not an administrator of', 'instagram-feed' ), 'disclaimerMentions' => __( 'Due to Instagram’s limitations, you need to connect a business account to display a Mentions timeline', 'instagram-feed' ), 'disclaimerHashtag' => __( 'Due to Instagram’s limitations, you need to connect a business account to display a Hashtag feed', 'instagram-feed' ), 'notSureToolTip' => __( 'Select "Personal" if displaying a regular feed of posts, as this can display feeds from either a Personal or Business account. For displaying a Hashtag or Tagged feed, you must have an Instagram Business account. If needed, you can convert a Personal account into a Business account by following the directions {link}here{link}.', 'instagram-feed' ) ), 'footer' => array( 'heading' => __( 'Add feeds for popular social platforms with our other plugins', 'instagram-feed' ), ), 'personal' => __( 'Personal', 'instagram-feed' ), 'business' => __( 'Business', 'instagram-feed' ), 'notSure' => __( "I'm not sure", 'instagram-feed' ), ); } /** * For Other Platforms listed on the footer widget * * @return array * * @since 6.0 */ public static function builder_svg_icons() { $builder_svg_icons = array( 'youtube' => '', 'twitter' => '', 'instagram' => '', 'facebook' => '', 'reviews' => ' ', 'smash' => '', 'tag' => '', 'copy' => '', 'duplicate' => '', 'edit' => '', 'delete' => '', 'checkmark' => '', 'checkmarklarge' => '', 'information' => '', 'cog' => '', 'angleUp' => '', 'user_check' => '', 'users' => '', 'info' => '', 'list' => '', 'grid' => '', 'masonry' => '', 'carousel' => '', 'highlight' => '', 'desktop' => '', 'tablet' => '', 'mobile' => '', 'feed_layout' => '', 'color_scheme' => '', 'header' => '', 'article' => '', 'article_2' => '', 'like_box' => '', 'load_more' => '', 'lightbox' => '', 'source' => '', 'filter' => '', 'update' => '', 'sun' => '', 'moon' => '', 'visual' => '', 'text' => '', 'background' => '', 'cursor' => '', 'link' => '', 'thumbnail' => '', 'halfwidth' => '', 'fullwidth' => '', 'boxed' => '', 'corner' => '', 'preview' => '', 'flag' => '', 'copy2' => '', 'timelineIcon' => ' ', 'photosIcon' => ' ', 'videosIcon' => ' ', 'albumsIcon' => ' ', 'eventsIcon' => ' ', 'reviewsIcon' => ' ', 'featuredpostIcon' => ' ', 'singlealbumIcon' => ' ', 'socialwallIcon' => ' ', 'addPage' => '', 'addWidget' => '', 'plus' => '', 'eye1' => '', 'eyePreview' => '', 'facebookShare' => '', 'twitterShare' => '', 'linkedinShare' => '', 'mailShare' => '', 'successNotification' => '', 'errorNotification' => '', 'messageNotification' => '', 'albumsPreview' => ' ', 'featuredPostPreview' => ' ', 'issueSinglePreview' => ' ', 'playButton' => '', 'spinner' => '', 'rocket' => '', 'follow' => '', 'picture' => '', 'caption' => '', 'heart' => '', 'sort' => '', 'shop' => '', 'headerUser' => '', 'headerPhoto' => '', 'imageChooser' => '', 'usertimelineIcon' => ' ', 'publichashtagIcon' => ' ', 'taggedpostsIcon' => ' ', 'socialwall1Icon' => ' ', 'publichashtagIconFree' => '', 'taggedpostsIconFree' => '', 'socialwall1IconFree' => ' ', 'user' => '', 'hashtag' => '', 'mention' => '', 'tooltipHelpSvg' => '', 'shoppableDisabled' => ' ', 'shoppableEnabled' => ' ', 'ctaBoxes' => array( 'hashtag' => '', 'layout' => '', 'popups' => '', 'filter' => '' ), 'camera' => '', 'uploadFile' => '', 'addRoundIcon' =>'', 'loaderSVG' => '' ); return $builder_svg_icons; } public static function sb_other_plugins_modal() { check_ajax_referer( 'sbi_nonce', 'sbi_nonce' ); if ( ! current_user_can( 'activate_plugins' ) || ! current_user_can( 'install_plugins' ) ) { wp_send_json_error(); } $plugin = isset( $_POST['plugin'] ) ? sanitize_key( $_POST['plugin'] ) : ''; $sb_other_plugins = self::install_plugins_popup(); $plugin = isset( $sb_other_plugins[ $plugin ] ) ? $sb_other_plugins[ $plugin ] : false; if ( ! $plugin ) { wp_send_json_error(); } // Build the content for modals $output = '
' . $plugin['svgIcon'] . '

' . $plugin['name'] . 'Free

' . $plugin['author'] . '

' . $plugin['description'] . '

'; $plugin_install_data = array( 'step' => 'install', 'action' => 'sbi_install_addon', 'nonce' => wp_create_nonce( 'sbi-admin' ), 'plugin' => $plugin['plugin'], 'download_plugin' => $plugin['download_plugin'], ); if ( ! $plugin['installed'] ) { $output .= sprintf( "
", sbi_json_encode( $plugin_install_data ), __( 'Install', 'instagram-feed' ) ); } if ( $plugin['installed'] && ! $plugin['activated'] ) { $plugin_install_data['step'] = 'activate'; $plugin_install_data['action'] = 'sbi_activate_addon'; $output .= sprintf( "", sbi_json_encode( $plugin_install_data ), __( 'Activate', 'instagram-feed' ) ); } if ( $plugin['installed'] && $plugin['activated'] ) { $output .= sprintf( "", __( 'Plugin installed & activated', 'instagram-feed' ) ); } new \InstagramFeed\SBI_Response( true, array( 'output' => $output ) ); } /** * Plugins information for plugin install modal in all feeds page on select source flow * * @since 6.0 * * @return array */ public static function install_plugins_popup() { // get the WordPress's core list of installed plugins if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $installed_plugins = get_plugins(); $is_reviews_installed = false; $reviews_plugin = 'reviews-feed/sb-reviews.php'; if ( isset( $installed_plugins['reviews-feed-pro/sb-reviews-pro.php'] ) ) { $is_reviews_installed = true; $reviews_plugin = 'reviews-feed-pro/sb-reviews-pro.php'; } elseif ( isset( $installed_plugins['reviews-feed/sb-reviews.php'] ) ) { $is_reviews_installed = true; } $is_facebook_installed = false; $facebook_plugin = 'custom-facebook-feed/custom-facebook-feed.php'; if ( isset( $installed_plugins['custom-facebook-feed-pro/custom-facebook-feed.php'] ) ) { $is_facebook_installed = true; $facebook_plugin = 'custom-facebook-feed/custom-facebook-feed.php'; } elseif ( isset( $installed_plugins['custom-facebook-feed/custom-facebook-feed.php'] ) ) { $is_facebook_installed = true; } $is_twitter_installed = false; $twitter_plugin = 'custom-twitter-feeds/custom-twitter-feed.php'; if ( isset( $installed_plugins['custom-twitter-feeds-pro/custom-twitter-feed.php'] ) ) { $is_twitter_installed = true; $twitter_plugin = 'custom-twitter-feeds-pro/custom-twitter-feed.php'; } elseif ( isset( $installed_plugins['custom-twitter-feeds/custom-twitter-feed.php'] ) ) { $is_twitter_installed = true; } $is_youtube_installed = false; $youtube_plugin = 'feeds-for-youtube/youtube-feed.php'; if ( isset( $installed_plugins['youtube-feed-pro/youtube-feed.php'] ) ) { $is_youtube_installed = true; $youtube_plugin = 'youtube-feed-pro/youtube-feed.php'; } elseif ( isset( $installed_plugins['feeds-for-youtube/youtube-feed.php'] ) ) { $is_youtube_installed = true; } $return = array( 'reviews' => array( 'displayName' => __( 'Reviews', 'instagram-feed' ), 'name' => __( 'Reviews Feed', 'instagram-feed' ), 'author' => __( 'By Smash Balloon', 'instagram-feed' ), 'description' => __( 'To display a Reviews feed, our Reviews plugin is required.
Increase conversions and build positive brand trust through Google and Yelp reviews from your customers. Provide social proof needed to turn visitors into customers.', 'instagram-feed' ), 'dashboard_permalink' => admin_url( 'admin.php?page=sbr' ), 'svgIcon' => ' ', 'installed' => $is_reviews_installed, 'activated' => is_plugin_active( $reviews_plugin ), 'plugin' => $reviews_plugin, 'download_plugin' => 'https://downloads.wordpress.org/plugin/reviews-feed.zip', ), 'facebook' => array( 'displayName' => __( 'Facebook', 'instagram-feed' ), 'name' => __( 'Facebook Feed', 'instagram-feed' ), 'author' => __( 'By Smash Balloon', 'instagram-feed' ), 'description' => __( 'To display a Facebook feed, our Facebook plugin is required.
It provides a clean and beautiful way to add your Facebook posts to your website. Grab your visitors attention and keep them engaged with your site longer.', 'instagram-feed' ), 'dashboard_permalink' => admin_url( 'admin.php?page=cff-feed-builder' ), 'svgIcon' => '', 'installed' => $is_facebook_installed, 'activated' => is_plugin_active( $facebook_plugin ), 'plugin' => $facebook_plugin, 'download_plugin' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip', ), 'twitter' => array( 'displayName' => __( 'Twitter', 'instagram-feed' ), 'name' => __( 'Twitter Feed', 'instagram-feed' ), 'author' => __( 'By Smash Balloon', 'instagram-feed' ), 'description' => __( 'Custom Twitter Feeds is a highly customizable way to display tweets from your Twitter account. Promote your latest content and update your site content automatically.', 'instagram-feed' ), 'dashboard_permalink' => admin_url( 'admin.php?page=custom-twitter-feeds' ), 'svgIcon' => '', 'installed' => $is_twitter_installed, 'activated' => is_plugin_active( $twitter_plugin ), 'plugin' => $twitter_plugin, 'download_plugin' => 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip', ), 'youtube' => array( 'displayName' => __( 'YouTube', 'instagram-feed' ), 'name' => __( 'Feeds for YouTube', 'instagram-feed' ), 'author' => __( 'By Smash Balloon', 'instagram-feed' ), 'description' => __( 'To display a YouTube feed, our YouTube plugin is required. It provides a simple yet powerful way to display videos from YouTube on your website, Increasing engagement with your channel while keeping visitors on your website.', 'instagram-feed' ), 'dashboard_permalink' => admin_url( 'admin.php?page=youtube-feed' ), 'svgIcon' => '', 'installed' => $is_youtube_installed, 'activated' => is_plugin_active( $youtube_plugin ), 'plugin' => $youtube_plugin, 'download_plugin' => 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip', ), ); if ( version_compare(PHP_VERSION, '7.1.0') < 0 ) { if ( isset( $return['reviews'] ) ) { unset( $return['reviews'] ); } } return $return; } /** * Gets a list of info * Used in multiple places in the feed creator * Other Platforms + Social Links * Upgrade links * * @return array * * @since 6.0 */ public static function get_smashballoon_info() { $smash_info = array( 'colorSchemes' => array( 'facebook' => '#006BFA', 'twitter' => '#1B90EF', 'instagram' => '#BA03A7', 'youtube' => '#EB2121', 'linkedin' => '#007bb6', 'mail' => '#666', 'smash' => '#EB2121' ), 'upgrade' => array( 'name' => __( 'Upgrade to Pro', 'instagram-feed' ), 'icon' => 'instagram', 'link' => 'https://smashballoon.com/instagram-feed/' ), 'platforms' => array( array( 'name' => __( 'Facebook Feed', 'instagram-feed' ), 'icon' => 'facebook', 'link' => 'https://smashballoon.com/custom-facebook-feed/?utm_campaign=instagram-free&utm_source=balloon&utm_medium=facebook' ), array( 'name' => __( 'Twitter Feed', 'instagram-feed' ), 'icon' => 'twitter', 'link' => 'https://smashballoon.com/custom-twitter-feeds/?utm_campaign=instagram-free&utm_source=balloon&utm_medium=twitter' ), array( 'name' => __( 'YouTube Feed', 'instagram-feed' ), 'icon' => 'youtube', 'link' => 'https://smashballoon.com/youtube-feed/?utm_campaign=instagram-free&utm_source=balloon&utm_medium=youtube' ), array( 'name' => __( 'Social Wall Plugin', 'instagram-feed' ), 'icon' => 'smash', 'link' => 'https://smashballoon.com/social-wall/?utm_campaign=instagram-free&utm_source=balloon&utm_medium=social-wall ', ) ), 'socialProfiles' => array( 'facebook' => 'https://www.facebook.com/SmashBalloon/', 'twitter' => 'https://twitter.com/smashballoon', ), 'morePlatforms' => array( 'instagram', 'youtube', 'twitter' ) ); return $smash_info; } /** * Text specific to onboarding. Will return an associative array 'active' => false * if onboarding has been dismissed for the user or there aren't any legacy feeds. * * @return array * * @since 4.0 */ public function get_onboarding_text() { // TODO: return if no legacy feeds $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( ! isset( $sbi_statuses_option['legacy_onboarding'] ) ) { return array( 'active' => false ); } if ( $sbi_statuses_option['legacy_onboarding']['active'] === false || self::onboarding_status() === 'dismissed' ) { return array( 'active' => false ); } $type = $sbi_statuses_option['legacy_onboarding']['type']; $text = array( 'active' => true, 'type' => $type, 'legacyFeeds' => array( 'heading' => __( 'Legacy Feed Settings', 'instagram-feed' ), 'description' => sprintf( __( 'These settings will impact %1$s legacy feeds on your site. You can learn more about what legacy feeds are and how they differ from new feeds %2$shere%3$s.', 'instagram-feed' ), '', '', '' ), ), 'getStarted' => __( 'You can now create and customize feeds individually. Click "Add New" to get started.', 'instagram-feed' ), ); if ( $type === 'single' ) { $text['tooltips'] = array( array( 'step' => 1, 'heading' => __( 'How you create a feed has changed', 'instagram-feed' ), 'p' => __( 'You can now create and customize feeds individually without using shortcode options.', 'instagram-feed' ) . ' ' . __( 'Click "Add New" to get started.', 'instagram-feed' ), 'pointer' => 'top' ), array( 'step' => 2, 'heading' => __( 'Your existing feed is here', 'instagram-feed' ), 'p' => __( 'You can edit your existing feed from here, and all changes will only apply to this feed.', 'instagram-feed' ), 'pointer' => 'top' ) ); } else { $text['tooltips'] = array( array( 'step' => 1, 'heading' => __( 'How you create a feed has changed', 'instagram-feed' ), 'p' => __( 'You can now create and customize feeds individually without using shortcode options.', 'instagram-feed' ) . ' ' . __( 'Click "Add New" to get started.', 'instagram-feed' ), 'pointer' => 'top' ), array( 'step' => 2, 'heading' => __( 'Your existing feeds are under "Legacy" feeds', 'instagram-feed' ), 'p' => __( 'You can edit the settings for any existing "legacy" feed (i.e. any feed created prior to this update) here.', 'instagram-feed' ) . ' ' . __( 'This works just like the old settings page and affects all legacy feeds on your site.', 'instagram-feed' ) ), array( 'step' => 3, 'heading' => __( 'Existing feeds work as normal', 'instagram-feed' ), 'p' => __( 'You don\'t need to update or change any of your existing feeds. They will continue to work as usual.', 'instagram-feed' ) . ' ' . __( 'This update only affects how new feeds are created and customized.', 'instagram-feed' ) ) ); } return $text; } public function get_customizer_onboarding_text() { if ( self::onboarding_status( 'customizer' ) === 'dismissed' ) { return array( 'active' => false ); } $text = array( 'active' => true, 'type' => 'customizer', 'tooltips' => array( array( 'step' => 1, 'heading' => __( 'Embedding a Feed', 'instagram-feed' ), 'p' => __( 'After you are done customizing the feed, click here to add it to a page or a widget.', 'instagram-feed' ), 'pointer' => 'top' ), array( 'step' => 2, 'heading' => __( 'Customize', 'instagram-feed' ), 'p' => __( 'Change your feed layout, color scheme, or customize individual feed sections here.', 'instagram-feed' ), 'pointer' => 'top' ), array( 'step' => 3, 'heading' => __( 'Settings', 'instagram-feed' ), 'p' => __( 'Update your feed source, filter your posts, or change advanced settings here.', 'instagram-feed' ), 'pointer' => 'top' ) ) ); return $text; } /** * Text related to the feed customizer * * @return array * * @since 6.0 */ public function get_customize_screens_text() { $text = array( 'common' => array( 'preview' => __( 'Preview', 'instagram-feed' ), 'help' => __( 'Help', 'instagram-feed' ), 'embed' => __( 'Embed', 'instagram-feed' ), 'save' => __( 'Save', 'instagram-feed' ), 'sections' => __( 'Sections', 'instagram-feed' ), 'enable' => __( 'Enable', 'instagram-feed' ), 'background' => __( 'Background', 'instagram-feed' ), 'text' => __( 'Text', 'instagram-feed' ), 'inherit' => __( 'Inherit from Theme', 'instagram-feed' ), 'size' => __( 'Size', 'instagram-feed' ), 'color' => __( 'Color', 'instagram-feed' ), 'height' => __( 'Height', 'instagram-feed' ), 'placeholder' => __( 'Placeholder', 'instagram-feed' ), 'select' => __( 'Select', 'instagram-feed' ), 'enterText' => __( 'Enter Text', 'instagram-feed' ), 'hoverState' => __( 'Hover State', 'instagram-feed' ), 'sourceCombine' => __( 'Combine sources from multiple platforms using our Social Wall plugin', 'instagram-feed' ), ), 'tabs' => array( 'customize' => __( 'Customize', 'instagram-feed' ), 'settings' => __( 'Settings', 'instagram-feed' ), ), 'overview' => array( 'feedLayout' => __( 'Feed Layout', 'instagram-feed' ), 'colorScheme' => __( 'Color Scheme', 'instagram-feed' ), 'header' => __( 'Header', 'instagram-feed' ), 'posts' => __( 'Posts', 'instagram-feed' ), 'likeBox' => __( 'Like Box', 'instagram-feed' ), 'loadMore' => __( 'Load More Button', 'instagram-feed' ), ), 'feedLayoutScreen' => array( 'layout' => __( 'Layout', 'instagram-feed' ), 'list' => __( 'List', 'instagram-feed' ), 'grid' => __( 'Grid', 'instagram-feed' ), 'masonry' => __( 'Masonry', 'instagram-feed' ), 'carousel' => __( 'Carousel', 'instagram-feed' ), 'feedHeight' => __( 'Feed Height', 'instagram-feed' ), 'number' => __( 'Number of Posts', 'instagram-feed' ), 'columns' => __( 'Columns', 'instagram-feed' ), 'desktop' => __( 'Desktop', 'instagram-feed' ), 'tablet' => __( 'Tablet', 'instagram-feed' ), 'mobile' => __( 'Mobile', 'instagram-feed' ), 'bottomArea' => array( 'heading' => __( 'Tweak Post Styles', 'instagram-feed' ), 'description' => __( 'Change post background, border radius, shadow etc.', 'instagram-feed' ), ) ), 'colorSchemeScreen' => array( 'scheme' => __( 'Scheme', 'instagram-feed' ), 'light' => __( 'Light', 'instagram-feed' ), 'dark' => __( 'Dark', 'instagram-feed' ), 'custom' => __( 'Custom', 'instagram-feed' ), 'customPalette' => __( 'Custom Palette', 'instagram-feed' ), 'background2' => __( 'Background 2', 'instagram-feed' ), 'text2' => __( 'Text 2', 'instagram-feed' ), 'link' => __( 'Link', 'instagram-feed' ), 'bottomArea' => array( 'heading' => __( 'Overrides', 'instagram-feed' ), 'description' => __( 'Colors that have been overridden from individual post element settings will not change. To change them, you will have to reset overrides.', 'instagram-feed' ), 'ctaButton' => __( 'Reset Overrides.', 'instagram-feed' ), ) ), 'headerScreen' => array( 'headerType' => __( 'Header Type', 'instagram-feed' ), 'visual' => __( 'Visual', 'instagram-feed' ), 'coverPhoto' => __( 'Cover Photo', 'instagram-feed' ), 'nameAndAvatar' => __( 'Name and avatar', 'instagram-feed' ), 'about' => __( 'About (bio and Likes)', 'instagram-feed' ), 'displayOutside' => __( 'Display outside scrollable area', 'instagram-feed' ), 'icon' => __( 'Icon', 'instagram-feed' ), 'iconImage' => __( 'Icon Image', 'instagram-feed' ), 'iconColor' => __( 'Icon Color', 'instagram-feed' ), ), // all Lightbox in common // all Load More in common 'likeBoxScreen' => array( 'small' => __( 'Small', 'instagram-feed' ), 'large' => __( 'Large', 'instagram-feed' ), 'coverPhoto' => __( 'Cover Photo', 'instagram-feed' ), 'customWidth' => __( 'Custom Width', 'instagram-feed' ), 'defaultSetTo' => __( 'By default, it is set to auto', 'instagram-feed' ), 'width' => __( 'Width', 'instagram-feed' ), 'customCTA' => __( 'Custom CTA', 'instagram-feed' ), 'customCTADescription' => __( 'This toggles the custom CTA like "Show now" and "Contact"', 'instagram-feed' ), 'showFans' => __( 'Show Fans', 'instagram-feed' ), 'showFansDescription' => __( 'Show visitors which of their friends follow your page', 'instagram-feed' ), 'displayOutside' => __( 'Display outside scrollable area', 'instagram-feed' ), 'displayOutsideDescription' => __( 'Make the like box fixed by moving it outside the scrollable area', 'instagram-feed' ), ), 'postsScreen' => array( 'thumbnail' => __( 'Thumbnail', 'instagram-feed' ), 'half' => __( 'Half width', 'instagram-feed' ), 'full' => __( 'Full width', 'instagram-feed' ), 'useFull' => __( 'Use full width layout when post width is less than 500px', 'instagram-feed' ), 'postStyle' => __( 'Post Style', 'instagram-feed' ), 'editIndividual' => __( 'Edit Individual Elements', 'instagram-feed' ), 'individual' => array( 'description' => __( 'Hide or show individual elements of a post or edit their options', 'instagram-feed' ), 'name' => __( 'Name', 'instagram-feed' ), 'edit' => __( 'Edit', 'instagram-feed' ), 'postAuthor' => __( 'Post Author', 'instagram-feed' ), 'postText' => __( 'Post Text', 'instagram-feed' ), 'date' => __( 'Date', 'instagram-feed' ), 'photosVideos' => __( 'Photos/Videos', 'instagram-feed' ), 'likesShares' => __( 'Likes, Shares and Comments', 'instagram-feed' ), 'eventTitle' => __( 'Event Title', 'instagram-feed' ), 'eventDetails' => __( 'Event Details', 'instagram-feed' ), 'postAction' => __( 'Post Action Links', 'instagram-feed' ), 'sharedPostText' => __( 'Shared Post Text', 'instagram-feed' ), 'sharedLinkBox' => __( 'Shared Link Box', 'instagram-feed' ), 'postTextDescription' => __( 'The main text of the Instagram post', 'instagram-feed' ), 'maxTextLength' => __( 'Maximum Text Length', 'instagram-feed' ), 'characters' => __( 'Characters', 'instagram-feed' ), 'linkText' => __( 'Link text to Instagram post', 'instagram-feed' ), 'postDateDescription' => __( 'The date of the post', 'instagram-feed' ), 'format' => __( 'Format', 'instagram-feed' ), 'custom' => __( 'Custom', 'instagram-feed' ), 'learnMoreFormats' => '' . __( 'Learn more about custom formats', 'instagram-feed' ) . '', 'addTextBefore' => __( 'Add text before date', 'instagram-feed' ), 'addTextBeforeEG' => __( 'E.g. Posted', 'instagram-feed' ), 'addTextAfter' => __( 'Add text after date', 'instagram-feed' ), 'addTextAfterEG' => __( 'E.g. - posted date', 'instagram-feed' ), 'timezone' => __( 'Timezone', 'instagram-feed' ), 'tzDescription' => __( 'Timezone settings are global across all feeds. To update it use the global settings.', 'instagram-feed' ), 'tzCTAText' => __( 'Go to Global Settings', 'instagram-feed' ), 'photosVideosDescription' => __( 'Any photos or videos in your posts', 'instagram-feed' ), 'useOnlyOne' => __( 'Use only one image per post', 'instagram-feed' ), 'postActionLinksDescription' => __( 'The "View on Instagram" and "Share" links at the bottom of each post', 'instagram-feed' ), 'viewOnFBLink' => __( 'View on Instagram link', 'instagram-feed' ), 'viewOnFBLinkDescription' => __( 'Toggle "View on Instagram" link below each post', 'instagram-feed' ), 'customizeText' => __( 'Customize Text', 'instagram-feed' ), 'shareLink' => __( 'Share Link', 'instagram-feed' ), 'shareLinkDescription' => __( 'Toggle "Share" link below each post', 'instagram-feed' ), 'likesSharesDescription' => __( 'The comments box displayed at the bottom of each timeline post', 'instagram-feed' ), 'iconTheme' => __( 'Icon Theme', 'instagram-feed' ), 'auto' => __( 'Auto', 'instagram-feed' ), 'light' => __( 'Light', 'instagram-feed' ), 'dark' => __( 'Dark', 'instagram-feed' ), 'expandComments' => __( 'Expand comments box by default', 'instagram-feed' ), 'hideComment' => __( 'Hide comment avatars', 'instagram-feed' ), 'showLightbox' => __( 'Show comments in lightbox', 'instagram-feed' ), 'eventTitleDescription' => __( 'The title of an event', 'instagram-feed' ), 'eventDetailsDescription' => __( 'The information associated with an event', 'instagram-feed' ), 'textSize' => __( 'Text Size', 'instagram-feed' ), 'textColor' => __( 'Text Color', 'instagram-feed' ), 'sharedLinkBoxDescription' => __( "The link info box that's created when a link is shared in a Instagram post", 'instagram-feed' ), 'boxStyle' => __( 'Box Style', 'instagram-feed' ), 'removeBackground' => __( 'Remove background/border', 'instagram-feed' ), 'linkTitle' => __( 'Link Title', 'instagram-feed' ), 'linkURL' => __( 'Link URL', 'instagram-feed' ), 'linkDescription' => __( 'Link Description', 'instagram-feed' ), 'chars' => __( 'chars', 'instagram-feed' ), 'sharedPostDescription' => __( 'The description text associated with shared photos, videos, or links', 'instagram-feed' ), ), 'postType' => __( 'Post Type', 'instagram-feed' ), 'boxed' => __( 'boxed', 'instagram-feed' ), 'regular' => __( 'Regular', 'instagram-feed' ), 'indvidualProperties' => __( 'Individual Properties', 'instagram-feed' ), 'backgroundColor' => __( 'Background Color', 'instagram-feed' ), 'borderRadius' => __( 'Border Radius', 'instagram-feed' ), 'boxShadow' => __( 'Box Shadow', 'instagram-feed' ), ), 'shoppableFeedScreen' => array( 'heading1' => __( 'Upgrade to Pro and make your Instagram Feed Shoppable', 'instagram-feed' ), 'description1' => __( 'This feature links the post to the one specified in your caption.

Don’t want to add links to the caption? You can add links manually to each post.


', 'instagram-feed' ), 'heading2' => __( 'Tap “Add” or “Update” on an
image to add/update it’s URL', 'instagram-feed' ), ) ); $text['onboarding'] = $this->get_customizer_onboarding_text(); return $text; } /** * Returns an associate array of all existing sources along with their data * * @param int $page * * @return array * * @since 6.0 */ public static function get_source_list( $page = 1 ) { $args['page'] = $page; $source_data = SBI_Db::source_query( $args ); $encryption = new \SB_Instagram_Data_Encryption(); $return = array(); foreach ( $source_data as $source ) { $info = ! empty( $source['info'] ) ? json_decode( $encryption->decrypt( $source['info'] ), true ) : array(); $source['header_data'] = $info; $settings = array( 'gdpr' => 'no' ); $avatar = \SB_Instagram_Parse::get_avatar( $info, $settings ); if ( \SB_Instagram_Connected_Account::local_avatar_exists( $source['username'] ) ) { $source['local_avatar_url'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $source['username'] ); $source['local_avatar'] = \SB_Instagram_Connected_Account::get_local_avatar_url( $source['username'] ); } else { $source['local_avatar'] = false; } $source['avatar_url'] = is_bool( $avatar ) ? \SB_Instagram_Parse::get_avatar_url( $info, $settings ) : false; $source['just_added'] = ( ! empty( $_GET['sbi_username'] ) && isset( $info['username'] ) && $info['username'] === $_GET['sbi_username'] ); $source['error_encryption'] = false; if ( isset( $source['access_token'] ) && strpos( $source['access_token'], 'IG' ) === false && strpos( $source['access_token'], 'EA' ) === false && ! $encryption->decrypt( $source['access_token'] ) ) { $source['error_encryption'] = true; } $return[] = $source; } return $return; } /** * Get Links with UTM * * @return array * * @since 4.0 */ public static function get_links_with_utm() { $license_key = null; if ( get_option( 'sbi_license_key' ) ) { $license_key = get_option( 'sbi_license_key' ); } $all_access_bundle = sprintf( 'https://smashballoon.com/all-access/?license_key=%s&upgrade=true&utm_campaign=instagram-free&utm_source=all-feeds&utm_medium=footer-banner&utm_content=learn-more', $license_key ); $all_access_bundle_popup = sprintf( 'https://smashballoon.com/all-access/?license_key=%s&upgrade=true&utm_campaign=instagram-free&utm_source=balloon&utm_medium=all-access', $license_key ); $sourceCombineCTA = sprintf( 'https://smashballoon.com/social-wall/?license_key=%s&upgrade=true&utm_campaign=instagram-free&utm_source=customizer&utm_medium=sources&utm_content=social-wall', $license_key ); return array( 'allAccessBundle' => $all_access_bundle, 'popup' => array( 'allAccessBundle' => $all_access_bundle_popup, 'fbProfile' => 'https://www.facebook.com/SmashBalloon/', 'twitterProfile' => 'https://twitter.com/smashballoon', ), 'sourceCombineCTA' => $sourceCombineCTA, 'multifeedCTA' => 'https://smashballoon.com/extensions/multifeed/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=sources&utm_content=multifeed', 'doc' => 'https://smashballoon.com/docs/instagram/?utm_campaign=instagram-free&utm_source=support&utm_medium=view-documentation-button&utm_content=view-documentation', 'blog' => 'https://smashballoon.com/blog/?utm_campaign=instagram-free&utm_source=support&utm_medium=view-blog-button&utm_content=view-blog', 'gettingStarted' => 'https://smashballoon.com/docs/getting-started/?instagram&utm_campaign=instagram-free&utm_source=support&utm_medium=getting-started-button&utm_content=getting-started', ); } public static function get_social_wall_links() { return array( '' . __( 'All Feeds', 'instagram-feed' ) . '', '' . __( 'Settings', 'instagram-feed' ) . '', '' . __( 'oEmbeds', 'instagram-feed' ) . '', '' . __( 'Extensions', 'instagram-feed' ) . '', '' . __( 'About Us', 'instagram-feed' ) . '', '' . __( 'Support', 'instagram-feed' ) . '', ); } /** * Returns an associate array of all existing feeds along with their data * * @return array * * @since 6.0 */ public static function get_feed_list( $feeds_args = array() ) { if ( ! empty( $_GET['feed_id'] ) ) { return array(); } $feeds_data = SBI_Db::feeds_query( $feeds_args ); $i = 0; foreach ( $feeds_data as $single_feed ) { $args = array( 'feed_id' => '*' . $single_feed['id'], 'html_location' => array( 'content' ), ); $count = \SB_Instagram_Feed_Locator::count( $args ); $content_locations = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); // if this is the last page, add in the header footer and sidebar locations if ( count( $content_locations ) < SBI_Db::RESULTS_PER_PAGE ) { $args = array( 'feed_id' => '*' . $single_feed['id'], 'html_location' => array( 'header', 'footer', 'sidebar' ), 'group_by' => 'html_location', ); $other_locations = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); $locations = array(); $combined_locations = array_merge( $other_locations, $content_locations ); } else { $combined_locations = $content_locations; } foreach ( $combined_locations as $location ) { $page_text = get_the_title( $location['post_id'] ); if ( $location['html_location'] === 'header' ) { $html_location = __( 'Header', 'instagram-feed' ); } elseif ( $location['html_location'] === 'footer' ) { $html_location = __( 'Footer', 'instagram-feed' ); } elseif ( $location['html_location'] === 'sidebar' ) { $html_location = __( 'Sidebar', 'instagram-feed' ); } else { $html_location = __( 'Content', 'instagram-feed' ); } $shortcode_atts = json_decode( $location['shortcode_atts'], true ); $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array(); $full_shortcode_string = '[instagram-feed'; foreach ( $shortcode_atts as $key => $value ) { if ( ! empty( $value ) ) { $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"'; } } $full_shortcode_string .= ']'; $locations[] = array( 'link' => esc_url( get_the_permalink( $location['post_id'] ) ), 'page_text' => $page_text, 'html_location' => $html_location, 'shortcode' => $full_shortcode_string ); } $feeds_data[ $i ]['instance_count'] = $count; $feeds_data[ $i ]['location_summary'] = $locations; $settings = json_decode( $feeds_data[ $i ]['settings'], true ); $settings['feed'] = $single_feed['id']; $instagram_feed_settings = new \SB_Instagram_Settings( $settings, sbi_defaults() ); $feeds_data[ $i ]['settings'] = $instagram_feed_settings->get_settings(); $i++; } return $feeds_data; } /** * Returns an associate array of all existing sources along with their data * * @return array * * @since 4.0 */ public function get_legacy_feed_list() { if ( ! empty( $_GET['feed_id'] ) ) { return array(); } $sbi_statuses = get_option( 'sbi_statuses', array() ); $sources_list = self::get_source_list(); if ( empty( $sbi_statuses['support_legacy_shortcode'] ) ) { return array(); } $args = array( 'html_location' => array( 'header', 'footer', 'sidebar', 'content' ), 'group_by' => 'shortcode_atts', 'page' => 1 ); $feeds_data = \SB_Instagram_Feed_Locator::legacy_instagram_feed_locator_query( $args ); if ( empty( $feeds_data ) ) { $args = array( 'html_location' => array( 'header', 'footer', 'sidebar', 'content' ), 'group_by' => 'shortcode_atts', 'page' => 1 ); $feeds_data = \SB_Instagram_Feed_Locator::legacy_instagram_feed_locator_query( $args ); } $feed_saver = new SBI_Feed_Saver( 'legacy' ); $settings = $feed_saver->get_feed_settings(); $default_type = 'timeline'; if ( isset( $settings['feedtype'] ) ) { $default_type = $settings['feedtype']; } elseif ( isset( $settings['type'] ) ) { if ( strpos( $settings['type'], ',' ) === false ) { $default_type = $settings['type']; } } $i = 0; $reindex = false; foreach ( $feeds_data as $single_feed ) { $args = array( 'shortcode_atts' => $single_feed['shortcode_atts'], 'html_location' => array( 'content' ), ); $content_locations = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); $count = \SB_Instagram_Feed_Locator::count( $args ); if ( count( $content_locations ) < SBI_Db::RESULTS_PER_PAGE ) { $args = array( 'feed_id' => $single_feed['feed_id'], 'html_location' => array( 'header', 'footer', 'sidebar' ), 'group_by' => 'html_location' ); $other_locations = \SB_Instagram_Feed_Locator::instagram_feed_locator_query( $args ); $combined_locations = array_merge( $other_locations, $content_locations ); } else { $combined_locations = $content_locations; } $locations = array(); foreach ( $combined_locations as $location ) { $page_text = get_the_title( $location['post_id'] ); if ( $location['html_location'] === 'header' ) { $html_location = __( 'Header', 'instagram-feed' ); } elseif ( $location['html_location'] === 'footer' ) { $html_location = __( 'Footer', 'instagram-feed' ); } elseif ( $location['html_location'] === 'sidebar' ) { $html_location = __( 'Sidebar', 'instagram-feed' ); } else { $html_location = __( 'Content', 'instagram-feed' ); } $shortcode_atts = json_decode( $location['shortcode_atts'], true ); $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array(); $full_shortcode_string = '[instagram-feed'; foreach ( $shortcode_atts as $key => $value ) { if ( ! empty( $value ) ) { if ( is_array( $value ) ) { $value = implode( ',', $value ); } $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"'; } } $full_shortcode_string .= ']'; $locations[] = array( 'link' => esc_url( get_the_permalink( $location['post_id'] ) ), 'page_text' => $page_text, 'html_location' => $html_location, 'shortcode' => $full_shortcode_string ); } $shortcode_atts = json_decode( $feeds_data[ $i ]['shortcode_atts'], true ); $shortcode_atts = is_array( $shortcode_atts ) ? $shortcode_atts : array(); $full_shortcode_string = '[instagram-feed'; foreach ( $shortcode_atts as $key => $value ) { if ( ! empty( $value ) ) { if ( is_array( $value ) ) { $value = implode( ',', $value ); } $full_shortcode_string .= ' ' . esc_html( $key ) . '="' . esc_html( $value ) . '"'; } } $full_shortcode_string .= ']'; $feeds_data[ $i ]['shortcode'] = $full_shortcode_string; $feeds_data[ $i ]['instance_count'] = $count; $feeds_data[ $i ]['location_summary'] = $locations; $feeds_data[ $i ]['feed_name'] = self::get_legacy_feed_name( $sources_list, $feeds_data[ $i ]['feed_id'] ); $feeds_data[ $i ]['feed_type'] = $default_type; if ( isset( $shortcode_atts['feedtype'] ) ) { $feeds_data[ $i ]['feed_type'] = $shortcode_atts['feedtype']; } elseif ( isset( $shortcode_atts['type'] ) ) { if ( strpos( $shortcode_atts['type'], ',' ) === false ) { $feeds_data[ $i ]['feed_type'] = $shortcode_atts['type']; } } if ( isset( $feeds_data[ $i ]['id'] ) ) { unset( $feeds_data[ $i ]['id'] ); } if ( isset( $feeds_data[ $i ]['html_location'] ) ) { unset( $feeds_data[ $i ]['html_location'] ); } if ( isset( $feeds_data[ $i ]['last_update'] ) ) { unset( $feeds_data[ $i ]['last_update'] ); } if ( isset( $feeds_data[ $i ]['post_id'] ) ) { unset( $feeds_data[ $i ]['post_id'] ); } if ( ! empty( $shortcode_atts['feed'] ) ) { $reindex = true; unset( $feeds_data[ $i ] ); } if ( isset( $feeds_data[ $i ]['shortcode_atts'] ) ) { unset( $feeds_data[ $i ]['shortcode_atts'] ); } $i++; } if ( $reindex ) { $feeds_data = array_values( $feeds_data ); } // if there were no feeds found in the locator table we still want the legacy settings to be available // if it appears as though they had used version 3.x or under at some point. if ( empty( $feeds_data ) && ! is_array( $sbi_statuses['support_legacy_shortcode'] ) && ( $sbi_statuses['support_legacy_shortcode'] ) ) { $feeds_data = array( array( 'feed_id' => __( 'Legacy Feed', 'instagram-feed' ) . ' ' . __( '(unknown location)', 'instagram-feed' ), 'feed_name' => __( 'Legacy Feed', 'instagram-feed' ) . ' ' . __( '(unknown location)', 'instagram-feed' ), 'shortcode' => '[instagram-feed]', 'feed_type' => '', 'instance_count' => false, 'location_summary' => array() ) ); } return $feeds_data; } public static function get_legacy_feed_name( $sources_list, $source_id ) { foreach ( $sources_list as $source ) { if ( $source['account_id'] == $source_id ) { return $source['username']; } } return $source_id; } /** * Status of the onboarding sequence for specific user * * @return string|boolean * * @since 6.0 */ public static function onboarding_status( $type = 'newuser' ) { $onboarding_statuses = get_user_meta( get_current_user_id(), 'sbi_onboarding', true ); $status = false; if ( ! empty( $onboarding_statuses ) ) { $statuses = maybe_unserialize( $onboarding_statuses ); $status = isset( $statuses[ $type ] ) ? $statuses[ $type ] : false; } return $status; } /** * Update status of onboarding sequence for specific user * * @return string|boolean * * @since 6.0 */ public static function update_onboarding_meta( $value, $type = 'newuser' ) { $onboarding_statuses = get_user_meta( get_current_user_id(), 'sbi_onboarding', true ); if ( ! empty( $onboarding_statuses ) ) { $statuses = maybe_unserialize( $onboarding_statuses ); $statuses[ $type ] = $value; } else { $statuses = array( $type => $value ); } $statuses = maybe_serialize( $statuses ); update_user_meta( get_current_user_id(), 'sbi_onboarding', $statuses ); } /** * Used to dismiss onboarding using AJAX * * @since 6.0 */ public static function after_dismiss_onboarding() { check_ajax_referer( 'sbi-admin', 'nonce' ); $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); if ( current_user_can( $cap ) ) { $type = 'newuser'; if ( isset( $_POST['was_active'] ) ) { $type = sanitize_key( $_POST['was_active'] ); } self::update_onboarding_meta( 'dismissed', $type ); } wp_die(); } public static function add_customizer_att( $atts ) { if ( ! is_array( $atts ) ) { $atts = array(); } $atts['feedtype'] = 'customizer'; return $atts; } /** * Feed Builder Wrapper. * * @since 6.0 */ public function feed_builder() { include_once SBI_BUILDER_DIR . 'templates/builder.php'; } /** * For types listed on the top of the select feed type screen * * @return array * * @since 6.0 */ public function get_feed_types() { $feed_types = array( array( 'type' => 'user', 'title' => __( 'User Timeline', 'instagram-feed' ), 'description' => __( 'Fetch posts from your Instagram profile', 'instagram-feed' ), 'icon' => 'usertimelineIcon' ), /* array( 'type' => 'hashtag', 'title' => __( 'Public Hashtag', 'instagram-feed' ), 'description' => __( 'Fetch posts from a public Instagram hashtag', 'instagram-feed' ), 'tooltip' => __( 'Hashtag feeds require a connected Instagram business account', 'instagram-feed' ), 'businessRequired' => true, 'icon' => 'publichashtagIcon' ), array( 'type' => 'tagged', 'title' => __( 'Tagged Posts', 'instagram-feed' ), 'description' => __( 'Display posts your Instagram account has been tagged in', 'instagram-feed' ), 'tooltip' => __( 'Tagged posts feeds require a connected Instagram business account', 'instagram-feed' ), 'businessRequired' => true, 'icon' => 'taggedpostsIcon' ), array( 'type' => 'socialwall', 'title' => __( 'Social Wall', 'instagram-feed' ) . '', 'description' => __( 'Create a feed with sources from different social platforms', 'instagram-feed' ), 'icon' => 'socialwall1Icon' ) */ ); return $feed_types; } /** * For types listed on the bottom of the select feed type screen * * @return array * * @since 6.0 */ public function get_advanced_feed_types() { $feed_types = array( array( 'type' => 'hashtag', 'title' => __( 'Public Hashtag', 'instagram-feed' ), 'description' => __( 'Fetch posts from a public Instagram hashtag', 'instagram-feed' ), 'tooltip' => __( 'Hashtag feeds require a connected Instagram business account', 'instagram-feed' ), 'businessRequired' => true, 'icon' => 'publichashtagIcon' ), array( 'type' => 'tagged', 'title' => __( 'Tagged Posts', 'instagram-feed' ), 'description' => __( 'Display posts your Instagram account has been tagged in', 'instagram-feed' ), 'tooltip' => __( 'Tagged posts feeds require a connected Instagram business account', 'instagram-feed' ), 'businessRequired' => true, 'icon' => 'taggedpostsIcon' ), array( 'type' => 'socialwall', 'title' => __( 'Social Wall', 'instagram-feed' ), 'description' => __( 'Create a feed with sources from different social platforms', 'instagram-feed' ), 'icon' => 'socialwall1Icon' ), ); return $feed_types; } /** * Personal Account * * @return array * * @since 6.0.8 */ public static function personal_account_screen_text() { return array( 'mainHeading1' => __( 'We’re almost there...', 'instagram-feed' ), 'mainHeading2' => __( 'Update Personal Account', 'instagram-feed' ), 'mainHeading3' => __( 'Add Instagram Profile Picture and Bio', 'instagram-feed' ), 'mainDescription' => __( 'Instagram does not provide us access to your profile picture or bio for personal accounts. Would you like to set up a custom profile photo and bio?.', 'instagram-feed' ), 'bioLabel' => __( 'Bio (140 Characters)', 'instagram-feed' ), 'bioPlaceholder' => __( 'Add your profile bio here', 'instagram-feed' ), 'confirmBtn' => __( 'Yes, let\'s do it', 'instagram-feed' ), 'cancelBtn' => __( 'No, maybe later', 'instagram-feed' ), 'uploadBtn' => __( 'Upload Profile Picture', 'instagram-feed' ) ); } } inc/Builder/SBI_Post_Set.php000064400000011210150515074560011654 0ustar00feed_id = $feed_id; $this->transient_name = '*' . $feed_id; $this->data = array(); } /** * @return array|object * * @since 6.0 */ public function get_data() { return $this->data; } /** * @return array|object * * @since 6.0 */ public function get_comments_data() { return $this->comments_data; } /** * @return array * * @since 6.0 */ public function get_feed_settings() { return $this->feed_settings; } /** * @return array * * @since 6.0 */ public function get_converted_settings() { return $this->converted_settings; } /** * Sets the settings in builder form as well as converted * settings for general use in the plugin * * @since 6.0 */ public function init( $customizerBuilder = false, $previewSettings = false ) { $saver = new SBI_Feed_Saver( $this->feed_id ); if( $customizerBuilder && $previewSettings != false){ $this->feed_settings = $saver->get_feed_settings_preview( $previewSettings ); } else{ $this->feed_settings = $saver->get_feed_settings(); } $this->converted_settings = SBI_Post_Set::builder_to_general_settings_convert( $this->feed_settings ); } /** * Gathers posts from the API until the minimum number of posts * for the feed are retrieved then stores the results * * @since 6.0 */ public function fetch() { $post_data = []; $this->data = $post_data; } /** * Gathers comments for posts. * * @return array * * @since 6.0 */ public function fetch_comments() { if ( empty( $this->data ) ) { return array(); } $comments = []; $this->comments_data = $comments; return $comments; } /** * Converts raw settings from the cff_feed_settings table into the * more general way that the "CFF_Shortcode" class, * "cff_get_processed_options" method does * * @param array $builder_settings * * @return array * * @since 6.0 */ public static function builder_to_general_settings_convert( $builder_settings ) { $settings_with_multiples = array(); foreach ( $settings_with_multiples as $array_setting ) { if ( is_array( $builder_settings[ $array_setting ] ) ) { $builder_settings[ $array_setting ] = implode( ',', $builder_settings[ $array_setting ] ); } } if ( isset( $builder_settings['sources'] ) && is_array($builder_settings['sources'])) { $access_tokens = array(); $ids = array(); $id_access_tokens = array(); $sources_setting = array(); foreach ( $builder_settings['sources'] as $source ) { $source_array = array(); if ( ! is_array( $source ) ) { $args = array( 'id' => $source ); if ( isset( $builder_settings['feedtype'] ) && $builder_settings['feedtype'] == 'events' ){ $args['privilege'] = 'events'; } $source_query = SBI_Db::source_query( $args ); if ( isset( $source_query[0] ) ) { $source_array = $source_query[0]; $sources_setting[] = $source_query[0]; } } else { $source_array = $source; } if ( ! empty( $source_array ) ) { $access_tokens[] = $source_array['access_token']; } } if ( ! empty( $sources_setting ) ) { $builder_settings['sources'] = $sources_setting; } } return $builder_settings; } /** * Convert settings from 3.x for use in the builder in 6.0+ * * @param array $atts * * @return array * * @since 6.0 */ public static function legacy_to_builder_convert( $atts = array() ) { $processed_settings = []; return $processed_settings; } /** * Settings that can include an array of values * * @return array * * @since 6.0 */ public static function get_settings_with_multiple() { $settings_with_multiples = []; return $settings_with_multiples; } /** * Used for changing the settings used for general front end feeds * * @param array $builder_settings * * @return array * * @since 6.0 */ public static function filter_general_settings( $builder_settings ) { return $builder_settings; } /** * Used for changing the settings for feeds being edited in the customizer * * @param array $processed_settings * * @return array * * @since 6.0 */ public static function filter_builder_settings( $processed_settings ) { return $processed_settings; } }inc/Builder/Tabs/SBI_Builder_Customizer_Tab.php000064400000006064150515074560015420 0ustar00 [ 'id' => 'customize', 'heading' => __( 'Customize', 'instagram-feed' ), 'sections' => SBI_Customize_Tab::get_sections() ], 'settings' => [ 'id' => 'settings', 'heading' => __( 'Settings', 'instagram-feed' ), 'sections' => SBI_Settings_Tab::get_sections() ] ]; } /** * Text Size Options * * * @since 4.0 * @access public * * @return array */ public static function get_text_size_options(){ return [ 'inherit' => __( 'Inherit', 'instagram-feed' ), '10' => '10px', '11' => '11px', '12' => '12px', '13' => '13px', '14' => '14px', '15' => '15px', '16' => '16px', '18' => '18px', '20' => '20px', '24' => '24px', '28' => '28px', '32' => '32px', '36' => '36px', '42' => '42px', '48' => '48px', '54' => '54px', '60' => '60px', ]; } /** * header Icons Options * * * @since 4.0 * @access public * * @return array */ public static function get_header_icons_options(){ return [ 'facebook-square' => 'Facebook 1', 'facebook' => 'Facebook 2', 'calendar' => 'Events 1', 'calendar-o' => 'Events 2', 'picture-o' => 'Photos', 'users' => 'People', 'thumbs-o-up' => 'Thumbs Up 1', 'thumbs-up' => 'Thumbs Up 2', 'comment-o' => 'Speech Bubble 1', 'comment' => 'Speech Bubble 2', 'ticket' => 'Ticket', 'list-alt' => 'News List', 'file' => 'File 1', 'file-o' => 'File 2', 'file-text' => 'File 3', 'file-text-o' => 'File 4', 'youtube-play ' => 'Video', 'youtube-play' => 'YouTube', 'vimeo-square' => 'Vimeo', ]; } /** * Date Format Options * * * @since 4.0 * @access public * * @return array */ public static function get_date_format_options(){ $original = strtotime('2016-07-25T17:30:00+0000'); return [ '1' => __('2 days ago','instagram-feed'), '2' => date('F jS, g:i a', $original), '3' => date('F jS', $original), '4' => date('D F jS', $original), '5' => date('l F jS', $original), '6' => date('D M jS, Y', $original), '7' => date('l F jS, Y', $original), '8' => date('l F jS, Y - g:i a', $original), '9' => date("l M jS, 'y", $original), '10' => date('m.d.y', $original), '18' => date('m.d.y - G:i', $original), '11' => date('m/d/y', $original), '12' => date('d.m.y', $original), '19' => date('d.m.y - G:i', $original), '13' => date('d/m/y', $original), '14' => date('d-m-Y, G:i', $original), '15' => date('jS F Y, G:i', $original), '16' => date('d M Y, G:i', $original), '17' => date('l jS F Y, G:i', $original), '18' => date('Y-m-d', $original), 'custom' => __('Custom','instagram-feed') ]; } }inc/Builder/Tabs/SBI_Settings_Tab.php000064400000024761150515074560013412 0ustar00 [ 'heading' => __( 'Sources', 'instagram-feed' ), 'icon' => 'source', 'controls' => self::get_settings_sources_controls() ], 'settings_filters_moderation' => [ 'heading' => __( 'Filters and Moderation', 'instagram-feed' ), 'icon' => 'filter', 'controls' => self::get_settings_filters_moderation_controls() ], 'settings_sort' => [ 'heading' => __( 'Sort', 'instagram-feed' ), 'icon' => 'sort', 'controls' => self::get_settings_sort_controls() ], 'settings_shoppable_feed' => [ 'heading' => __( 'Shoppable Feed', 'instagram-feed' ), 'icon' => 'shop', 'separator' => 'none', 'controls' => self::get_settings_shoppable_feed_controls() ], 'empty_sections' => [ 'heading' => '', 'isHeader' => true, ], 'settings_advanced' => [ 'heading' => __( 'Advanced', 'instagram-feed' ), 'icon' => 'cog', 'controls' => self::get_settings_advanced_controls() ] ]; } /** * Get Settings Tab Filters & Moderation Section * @since 4.0 * @return array */ static function get_settings_filters_moderation_controls(){ return [ [ 'type' => 'heading', 'strongHeading' => 'true', 'heading' => __( 'Show specific types of posts', 'instagram-feed' ) ], [ 'type' => 'checkbox', 'id' => 'reelsposts', 'label' => __( 'Reels', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'checkViewDisabled' => 'moderationMode', 'ajaxAction' => 'feedFlyPreview', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'top' => 20, 'bottom' => 20 ], [ 'type' => 'heading', 'heading' => __( 'Advanced', 'instagram-feed' ), 'proLabel' => true, 'description' => __( 'Visually moderate your feed or hide specific posts with Instagram Feed Pro.', 'instagram-feed' ), 'checkExtensionPopup' => 'filtermoderation', 'checkExtensionPopupLearnMore' => 'filtermoderation' ], [ 'type' => 'customview', 'viewId' => 'moderationmode', 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'switcher' => [ 'id' => 'enablemoderationmode', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'labelStrong' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], 'moderationTypes' => [ 'allow' => [ 'label' => __( 'Allow List', 'instagram-feed' ), 'description' => __( 'Hides post by default so you can select the ones you want to show', 'instagram-feed' ), ], 'block' => [ 'label' => __( 'Block List', 'instagram-feed' ), 'description' => __( 'Show all posts by default so you can select the ones you want to hide', 'instagram-feed' ), ] ] ], [ 'type' => 'heading', 'strongHeading' => 'true', 'heading' => __( 'Filters', 'instagram-feed' ), 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'textarea', 'id' => 'includewords', 'heading' => __( 'Only show posts containing', 'instagram-feed' ), 'tooltip' => __( 'Show your active stories from Instagram when your header avatar is clicked. Displays a colored ring around your avatar when a story is available.', 'instagram-feed' ), 'placeholder' => __( 'Add words here to only show posts containing these words', 'instagram-feed' ), 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'separator', 'top' => 10, 'bottom' => 10, 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'textarea', 'id' => 'excludewords', 'disabledInput' => true, 'heading' => __( 'Do not show posts containing', 'instagram-feed' ), 'tooltip' => __( 'Remove any posts containing these text strings, separating multiple strings using commas.', 'instagram-feed' ), 'placeholder' => __( 'Add words here to hide any posts containing these words', 'instagram-feed' ), 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'heading', 'strongHeading' => 'true', 'stacked' => 'true', 'heading' => __( 'Show specific types of posts', 'instagram-feed' ), 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'checkbox', 'id' => 'photosposts', 'label' => __( 'Photos', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'checkViewDisabled' => 'moderationMode', 'ajaxAction' => 'feedFlyPreview', 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'checkbox', 'id' => 'videosposts', 'label' => __( 'Feed Videos', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'checkViewDisabled' => 'moderationMode', 'ajaxAction' => 'feedFlyPreview', 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'checkbox', 'id' => 'igtvposts', 'label' => __( 'IGTV Videos', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'checkViewDisabled' => 'moderationMode', 'ajaxAction' => 'feedFlyPreview', 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'top' => 10, 'bottom' => 10, 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], [ 'type' => 'number', 'id' => 'offset', 'strongHeading' => 'true', 'stacked' => 'true', 'placeholder' => '0', 'fieldSuffix' => 'posts', 'heading' => __( 'Post Offset', 'instagram-feed' ), 'description' => __( 'This will skip the specified number of posts from displaying in the feed', 'instagram-feed' ), 'checkExtensionDimmed' => 'filtermoderation', 'checkExtensionPopup' => 'filtermoderation', 'disabledInput' => true, 'checkViewDisabled' => 'moderationMode' ], ]; } /** * Get Settings Tab Sort Section * @since 4.0 * @return array */ static function get_settings_sort_controls(){ return [ [ 'type' => 'toggleset', 'id' => 'sortby', 'heading' => __( 'Sort Posts by', 'instagram-feed' ), 'strongHeading' => 'true', 'ajaxAction' => 'feedFlyPreview', 'options' => [ [ 'value' => 'none', 'label' => __( 'Newest', 'instagram-feed' ) ], [ 'value' => 'likes', 'checkExtension' => 'postStyling', 'utmLink' => 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=load-more', 'proLabel' => true, 'label' => __( 'Likes', 'instagram-feed' ) ], [ 'value' => 'random', 'label' => __( 'Random', 'instagram-feed' ) ] ] ], ]; } /** * Get Settings Tab Shoppable Feed Section * @since 4.0 * @return array */ static function get_settings_shoppable_feed_controls(){ return [ [ 'type' => 'customview', 'condition' => ['shoppablefeed' => [false]], 'conditionHide' => true, 'viewId' => 'shoppabledisabled' ], [ 'type' => 'customview', 'condition' => ['shoppablefeed' => [true]], 'conditionHide' => true, 'viewId' => 'shoppableenabled' ], [ 'type' => 'customview', 'condition' => ['shoppablefeed' => [true]], 'conditionHide' => true, 'viewId' => 'shoppableselectedpost' ] ]; } /** * Get Settings Tab Advanced Section * @since 4.0 * @return array */ static function get_settings_advanced_controls(){ return [ [ 'type' => 'number', 'id' => 'maxrequests', 'strongHeading' => 'true', 'heading' => __( 'Max Concurrent API Requests', 'instagram-feed' ), 'description' => __( 'Change the number of maximum concurrent API requests. Not recommended unless directed by the support team.', 'instagram-feed' ), ], [ 'type' => 'switcher', 'id' => 'customtemplates', 'label' => __( 'Custom Templates', 'instagram-feed' ), 'description' => sprintf( __( 'The default HTML for the feed can be replaced with custom templates added to your theme\'s folder. Enable this setting to use these templates. Custom templates are not used in the feed editor. %sLearn More%s', 'instagram-feed' ), '', '' ), 'descriptionPosition' => 'bottom', 'reverse' => 'true', 'strongHeading' => 'true', 'labelStrong' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], ]; } /** * Get Settings TabSources Section * @since 6.0 * @return array */ static function get_settings_sources_controls(){ return [ [ 'type' => 'customview', 'viewId' => 'sources' ], ]; } } inc/Builder/Tabs/SBI_Customize_Tab.php000064400000117305150515074560013571 0ustar00 [ 'heading' => __( 'Feed Layout', 'instagram-feed' ), 'icon' => 'feed_layout', 'controls' => self::get_customize_feedlayout_controls() ], 'customize_colorschemes' => [ 'heading' => __( 'Color Scheme', 'instagram-feed' ), 'icon' => 'color_scheme', 'controls' => self::get_customize_colorscheme_controls() ], 'customize_sections' => [ 'heading' => __( 'Sections', 'instagram-feed' ), 'isHeader' => true, ], 'customize_header' => [ 'heading' => __( 'Header', 'instagram-feed' ), 'icon' => 'header', 'separator' => 'none', 'controls' => self::get_customize_header_controls() ], 'customize_posts' => [ 'heading' => __( 'Posts', 'instagram-feed' ), 'icon' => 'article', 'controls' => self::get_customize_posts_controls(), 'nested_sections' => [ 'images_videos' => [ 'heading' => __( 'Images and Videos', 'instagram-feed' ), 'icon' => 'picture', 'isNested' => 'true', 'separator' => 'none', 'controls' => self::get_nested_images_videos_controls(), ], ] ], 'customize_loadmorebutton' => [ 'heading' => __( 'Load More Button', 'instagram-feed' ), 'description' => '
', 'icon' => 'load_more', 'separator' => 'none', 'controls' => self::get_customize_loadmorebutton_controls() ], 'customize_followbutton' => [ 'heading' => __( 'Follow Button', 'instagram-feed' ), 'description' => '
', 'icon' => 'follow', 'separator' => 'none', 'controls' => self::get_customize_followbutton_controls() ], 'customize_lightbox' => [ 'heading' => __( 'Lightbox', 'instagram-feed' ), 'description' => __( 'Upgrade to Pro to add a modal when user clicks on a post.', 'custom-facebook-feed' ), 'proLabel' => true, 'icon' => 'lightbox', 'separator' => 'none', 'checkExtensionPopup' => 'lightbox', 'controls' => self::get_customize_lightbox_controls() ] ]; } /** * Get Customize Tab Feed Layout Section * @since 6.0 * @return array */ static function get_customize_feedlayout_controls(){ return [ [ 'type' => 'toggleset', 'id' => 'layout', 'heading' => __( 'Layout', 'instagram-feed' ), 'separator' => 'bottom', 'options' => [ [ 'value' => 'grid', 'icon' => 'grid', 'label' => __( 'Grid', 'instagram-feed' ) ], [ 'value' => 'carousel', 'icon' => 'carousel', 'checkExtension' => 'feedLayout', 'label' => __( 'Carousel', 'instagram-feed' ) ], [ 'value' => 'masonry', 'icon' => 'masonry', 'checkExtension' => 'feedLayout', 'label' => __( 'Masonry', 'instagram-feed' ) ], [ 'value' => 'highlight', 'icon' => 'highlight', 'checkExtension' => 'feedLayout', 'label' => __( 'Highlight', 'instagram-feed' ) ] ] ], //Carousel Settings [ 'type' => 'heading', 'heading' => __( 'Carousel Settings', 'instagram-feed' ), 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, ], /* [ 'type' => 'number', 'id' => 'carouselrows', 'layout' => 'half', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'ajaxAction' => 'feedFlyPreview', 'strongHeading' => 'false', 'stacked' => 'true', 'heading' => __( 'Rows', 'instagram-feed' ), ], */ [ 'type' => 'select', 'id' => 'carouselrows', 'layout' => 'half', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'ajaxAction' => 'feedFlyPreview', 'strongHeading' => 'false', 'stacked' => 'true', 'heading' => __( 'Rows', 'instagram-feed' ), 'options' => [ 1 => '1', 2 => '2' ] ], [ 'type' => 'select', 'id' => 'carouselloop', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Loop Type', 'instagram-feed' ), 'stacked' => 'true', 'options' => [ 'rewind' => __( 'Rewind', 'instagram-feed' ), 'infinity' => __( 'Infinity', 'instagram-feed' ), ] ], [ 'type' => 'number', 'id' => 'carouseltime', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'stacked' => 'true', 'layout' => 'half', 'fieldSuffix' => 'ms', 'heading' => __( 'Interval Time', 'instagram-feed' ), ], [ 'type' => 'checkbox', 'id' => 'carouselarrows', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'label' => __( 'Show Navigation Arrows', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', #'disabledInput' => true, 'options' => [ 'enabled' => 'true', 'disabled' => 'false' ] ], [ 'type' => 'checkbox', 'id' => 'carouselpag', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'label' => __( 'Show Pagination', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', #'disabledInput' => true, 'options' => [ 'enabled' => 'true', 'disabled' => 'false' ] ], [ 'type' => 'checkbox', 'id' => 'carouselautoplay', 'condition' => ['layout' => ['carousel']], 'conditionHide' => true, 'label' => __( 'Enable Autoplay', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', #'disabledInput' => true, 'options' => [ 'enabled' => 'true', 'disabled' => 'false' ] ], //HighLight Settings [ 'type' => 'heading', 'heading' => __( 'HighLight Settings', 'instagram-feed' ), 'condition' => ['layout' => ['highlight']], 'conditionHide' => true, ], [ 'type' => 'select', 'id' => 'highlighttype', 'condition' => ['layout' => ['highlight']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Type', 'instagram-feed' ), 'stacked' => 'true', 'options' => [ 'pattern' => __( 'Pattern', 'instagram-feed' ), 'id' => __( 'Post ID', 'instagram-feed' ), 'hashtag' => __( 'Hashtag', 'instagram-feed' ), ] ], [ 'type' => 'number', 'id' => 'highlightoffset', 'condition' => ['layout' => ['highlight'],'highlighttype' => ['pattern']], 'conditionHide' => true, 'stacked' => 'true', 'layout' => 'half', 'heading' => __( 'Offset', 'instagram-feed' ), ], [ 'type' => 'number', 'id' => 'highlightpattern', 'condition' => ['layout' => ['highlight'],'highlighttype' => ['pattern']], 'conditionHide' => true, 'stacked' => 'true', 'layout' => 'half', 'fieldSuffix' => 'posts', 'heading' => __( 'Highlight every', 'instagram-feed' ), ], [ 'type' => 'textarea', 'id' => 'highlightids', 'description' => __( 'Highlight posts with these IDs', 'instagram-feed' ), 'placeholder' => 'id1, id2', 'condition' => ['layout' => ['highlight'],'highlighttype' => ['id']], 'conditionHide' => true, 'stacked' => 'true' ], [ 'type' => 'textarea', 'id' => 'highlighthashtag', 'description' => __( 'Highlight posts with these hashtags', 'instagram-feed' ), 'placeholder' => '#hashtag1, #hashtag2', 'condition' => ['layout' => ['highlight'],'highlighttype' => ['hashtag']], 'conditionHide' => true, 'stacked' => 'true' ], [ 'type' => 'separator', 'top' => 20, 'bottom' => 10, 'condition' => ['layout' => ['highlight']], 'conditionHide' => true, ], [ 'type' => 'number', 'id' => 'height', 'fieldSuffix' => 'px', 'separator' => 'bottom', 'strongHeading' => 'true', 'heading' => __( 'Feed Height', 'instagram-feed' ), 'style' => ['#sb_instagram' => 'height:{{value}}px!important;overflow-y:auto;'], ], [ 'type' => 'number', 'id' => 'imagepadding', 'fieldSuffix' => 'px', 'separator' => 'bottom', 'strongHeading' => 'true', 'heading' => __( 'Padding', 'instagram-feed' ), 'style' => ['#sbi_images' => 'padding:{{value}}px!important;'], ], [ 'type' => 'heading', 'heading' => __( 'Number of Posts', 'instagram-feed' ), ], [ 'type' => 'number', 'id' => 'num', 'icon' => 'desktop', 'layout' => 'half', 'ajaxAction' => 'feedFlyPreview', 'strongHeading' => 'false', 'stacked' => 'true', 'heading' => __( 'Desktop', 'instagram-feed' ), ], [ 'type' => 'number', 'id' => 'nummobile', 'icon' => 'mobile', 'layout' => 'half', 'strongHeading' => 'false', 'stacked' => 'true', 'heading' => __( 'Mobile', 'instagram-feed' ), ], [ 'type' => 'separator', 'top' => 10, 'bottom' => 10, ], [ 'type' => 'heading', 'heading' => __( 'Columns', 'instagram-feed' ), 'condition' => ['layout' => ['grid','masonry']], 'conditionHide' => true, ], [ 'type' => 'select', 'id' => 'cols', 'conditionHide' => true, 'icon' => 'desktop', 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Desktop', 'instagram-feed' ), 'stacked' => 'true', 'options' => [ '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10', ] ], [ 'type' => 'select', 'id' => 'colstablet', 'conditionHide' => true, 'icon' => 'tablet', 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Tablet', 'instagram-feed' ), 'stacked' => 'true', 'options' => [ '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10', ] ], [ 'type' => 'select', 'id' => 'colsmobile', 'conditionHide' => true, 'icon' => 'mobile', 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Mobile', 'instagram-feed' ), 'stacked' => 'true', 'options' => [ '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10' => '10', ] ], ]; } /** * Get Customize Tab Color Scheme Section * @since 6.0 * @return array */ static function get_customize_colorscheme_controls(){ $feed_id = isset( $_GET['feed_id'] ) ? sanitize_key( $_GET['feed_id'] ) : ''; $color_scheme_array = [ [ 'type' => 'toggleset', 'id' => 'colorpalette', 'separator' => 'bottom', 'options' => [ [ 'value' => 'inherit', 'label' => __( 'Inherit from Theme', 'instagram-feed' ) ], [ 'value' => 'light', 'icon' => 'sun', 'label' => __( 'Light', 'instagram-feed' ) ], [ 'value' => 'dark', 'icon' => 'moon', 'label' => __( 'Dark', 'instagram-feed' ) ], [ 'value' => 'custom', 'icon' => 'cog', 'label' => __( 'Custom', 'instagram-feed' ) ] ] ], //Custom Color Palette [ 'type' => 'heading', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'heading' => __( 'Custom Palette', 'instagram-feed' ), ], [ 'type' => 'colorpicker', 'id' => 'custombgcolor1', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Background', 'custom-facebook-feed' ), 'style' => ['.sbi_header_palette_custom_'.$feed_id.',#sb_instagram.sbi_palette_custom_'.$feed_id.',#sbi_lightbox .sbi_lb-outerContainer .sbi_lb-dataContainer,#sbi_lightbox .sbi_lightbox_tooltip,#sbi_lightbox .sbi_share_close' => 'background:{{value}}!important;'], 'stacked' => 'true' ], /* [ 'type' => 'colorpicker', 'id' => 'customtextcolor1', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Text', 'custom-facebook-feed' ), 'style' => ['#sb_instagram.sbi_palette_custom_'.$feed_id.' .sbi_caption,#sbi_lightbox .sbi_lb-outerContainer .sbi_lb-dataContainer .sbi_lb-details .sbi_lb-caption,#sbi_lightbox .sbi_lb-outerContainer .sbi_lb-dataContainer .sbi_lb-number,#sbi_lightbox.sbi_lb-comments-enabled .sbi_lb-commentBox p' => 'color:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'customtextcolor2', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Text 2', 'custom-facebook-feed' ), 'style' => ['.sbi_header_palette_custom_'.$feed_id.' .sbi_bio,#sb_instagram.sbi_palette_custom_'.$feed_id.' .sbi_meta' => 'color:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'customlinkcolor1', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Link', 'custom-facebook-feed' ), 'style' => ['.sbi_header_palette_custom_'.$feed_id.' a,#sb_instagram.sbi_palette_custom_'.$feed_id.' .sbi_expand a,#sbi_lightbox .sbi_lb-outerContainer .sbi_lb-dataContainer .sbi_lb-details a,#sbi_lightbox.sbi_lb-comments-enabled .sbi_lb-commentBox .sbi_lb-commenter' => 'color:{{value}};'], 'stacked' => 'true' ], */ [ 'type' => 'colorpicker', 'id' => 'custombuttoncolor1', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Button 1', 'custom-facebook-feed' ), 'style' => ['#sb_instagram.sbi_palette_custom_'.$feed_id.' #sbi_load .sbi_load_btn' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'custombuttoncolor2', 'condition' => ['colorpalette' => ['custom']], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Button 2', 'custom-facebook-feed' ), 'style' => ['#sb_instagram.sbi_palette_custom_'.$feed_id.' #sbi_load .sbi_follow_btn a' => 'background:{{value}}!important;'], 'stacked' => 'true' ], ]; $color_overrides = []; $color_overrides_array = []; return array_merge($color_scheme_array,$color_overrides_array); } /** * Get Customize Tab Header Section * @since 6.0 * @return array */ static function get_customize_header_controls(){ return [ [ 'type' => 'switcher', 'id' => 'showheader', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 20, 'bottom' => 0, ], [ 'type' => 'select', 'id' => 'headersize', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'strongHeading' => 'true', 'separator' => 'bottom', 'heading' => __( 'Header Size', 'instagram-feed' ), 'options' => [ 'small' => __( 'Small', 'instagram-feed' ), 'medium' => __( 'Medium', 'instagram-feed' ), 'large' => __( 'Large', 'instagram-feed' ), ] ], [ 'type' => 'imagechooser', 'id' => 'customavatar', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'strongHeading' => 'true', 'separator' => 'bottom', 'heading' => __( 'Use Custom Avatar', 'instagram-feed' ), 'tooltip' => __( 'Upload your own custom image to use for the avatar. This is automatically retrieved from Instagram for Business accounts, but is not available for Personal accounts.', 'instagram-feed' ), 'placeholder' => __( 'No Image Added', 'instagram-feed' ) ], [ 'type' => 'heading', 'heading' => __( 'Text', 'instagram-feed' ), 'condition' => ['showheader' => [true]], ], /* [ 'type' => 'select', 'id' => 'headertextsize', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Size', 'instagram-feed' ), 'stacked' => 'true', 'style' => ['h3.sbi-preview-header-name' => 'font-size:{{value}}px!important;'], 'options' => SBI_Builder_Customizer_Tab::get_text_size_options() ], */ [ 'type' => 'colorpicker', 'id' => 'headercolor', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Color', 'instagram-feed' ), 'style' => ['.sbi_header_text > *, .sbi_bio_info > *' => 'color:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'headerprimarycolor', 'condition' => ['showheader' => [true], 'headerstyle' => 'boxed'], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Primary Color', 'instagram-feed' ), 'style' => [ '.sbi_header_style_boxed .sbi_bio_info > *' => 'color:{{value}}!important;', '.sbi_header_style_boxed' => 'background:{{value}}!important;' ], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'headersecondarycolor', 'condition' => ['showheader' => [true], 'headerstyle' => 'boxed'], 'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Secondary Color', 'instagram-feed' ), 'style' => ['.sbi_header_style_boxed .sbi_header_bar' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 10, 'bottom' => 10, ], [ 'type' => 'switcher', 'id' => 'showbio', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'label' => __( 'Show Bio Text', 'instagram-feed' ), 'tooltip' => __( 'Use your own custom bio text in the feed header. This is automatically retrieved from Instagram for Business accounts, but it not available for Personal accounts.', 'instagram-feed' ), 'stacked' => 'true', 'labelStrong' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'textarea', 'id' => 'custombio', 'placeholder' => __( 'Add custom bio', 'instagram-feed' ), 'condition' => ['showheader' => [true],'showbio' => [true]], //'conditionHide' => true, 'child' => 'true', 'stacked' => 'true' ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 10, 'bottom' => 10, ], [ 'type' => 'switcher', 'id' => 'headeroutside', 'condition' => ['showheader' => [true]], //'conditionHide' => true, 'label' => __( 'Show outside scrollable area', 'instagram-feed' ), 'stacked' => 'true', 'labelStrong' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 10, 'bottom' => 10, ], [ 'type' => 'heading', 'heading' => __( 'Advanced', 'instagram-feed' ), 'proLabel' => true, 'checkExtensionPopupLearnMore' => 'headerLayout', 'description' => __( 'Tweak the header styles and show your follower count with Instagram Feed Pro.', 'instagram-feed' ), ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 30, 'bottom' => 10, ], [ 'type' => 'switcher', 'id' => 'stories', 'condition' => ['showheader' => [true]], 'switcherTop' => true, //'conditionHide' => true, 'checkExtensionDimmed' => 'headerLayout', 'checkExtensionPopup' => 'headerLayout', 'heading' => __( 'Include Stories', 'instagram-feed' ), 'description' => __( 'You can view active stories by clicking the profile picture in the header. Instagram Business accounts only.

', 'instagram-feed' ), 'tooltip' => __( 'Show your active stories from Instagram when your header avatar is clicked. Displays a colored ring around your avatar when a story is available.', 'instagram-feed' ), 'stacked' => 'true', 'labelStrong' => 'true', 'layout' => 'half', 'reverse' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'number', 'id' => 'storiestime', 'condition' => ['showheader' => [true],'stories' => [true]], 'conditionHide' => true, 'strongHeading' => false, 'stacked' => 'true', 'placeholder' => '500', 'child' => true, 'checkExtensionDimmed' => 'headerLayout', 'checkExtensionPopup' => 'headerLayout', 'fieldSuffix' => 'milliseconds', 'heading' => __( 'Change Interval', 'instagram-feed' ), 'description' => __( 'This is the time a story displays for, before displaying the next one. Videos always change when the video is finished.', 'instagram-feed' ), 'descriptionPosition' => 'bottom' ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 25, 'bottom' => 10, ], [ 'type' => 'switcher', 'id' => 'showfollowers', 'condition' => ['showheader' => [true]], 'checkExtensionDimmed' => 'headerLayout', 'checkExtensionPopup' => 'headerLayout', //'conditionHide' => true, 'label' => __( 'Show number of followers', 'instagram-feed' ), 'stacked' => 'true', 'labelStrong' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 10, 'bottom' => 10, ], [ 'type' => 'toggleset', 'id' => 'headerstyle', 'condition' => ['showheader' => [true]], 'heading' => __( 'Header Style', 'instagram-feed' ), 'options' => [ [ 'value' => 'standard', 'label' => __( 'Standard', 'instagram-feed' ) ], [ 'value' => 'boxed', 'checkExtension' => 'headerLayout', 'label' => __( 'Boxed', 'instagram-feed' ) ], [ 'value' => 'centered', 'checkExtension' => 'headerLayout', 'label' => __( 'Centered', 'instagram-feed' ) ] ] ], ]; } /** * Get Customize Tab Posts Section * @since 6.0 * @return array */ static function get_customize_posts_controls(){ return [ [ 'type' => 'heading', 'heading' => __( 'Advanced', 'instagram-feed' ), 'proLabel' => true, 'checkExtensionPopupLearnMore' => 'postStyling', 'description' => __( 'These properties are available in the PRO version.', 'instagram-feed' ), ], [ 'type' => 'checkbox', 'id' => 'showcaption', 'label' => __( 'Caption', 'instagram-feed' ), 'labelStrong' => 'true', 'separator' => 'bottom', 'checkExtensionDimmed' => 'postStyling', 'checkExtensionPopup' => 'postStyling', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'checkbox', 'id' => 'showlikes', 'label' => __( 'Like and Comment Summary', 'instagram-feed' ), 'labelStrong' => 'true', 'checkExtensionDimmed' => 'postStyling', 'checkExtensionPopup' => 'postStyling', 'separator' => 'bottom', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'checkbox', 'id' => 'showlikes', 'label' => __( 'Hover State', 'instagram-feed' ), 'labelStrong' => 'true', 'checkExtensionDimmed' => 'postStyling', 'checkExtensionPopup' => 'postStyling', 'separator' => 'bottom', 'disabledInput' => true, 'options' => [ 'enabled' => true, 'disabled' => false ] ], ]; } /** * Get Customize Tab Posts Section * @since 6.0 * @return array */ static function get_nested_images_videos_controls(){ return [ [ 'type' => 'separator', 'top' => 20, 'bottom' => 20, ], [ 'type' => 'select', 'id' => 'imageres', 'strongHeading' => 'true', 'conditionHide' => true, 'stacked' => 'true', 'heading' => __( 'Resolution', 'instagram-feed' ), 'description' => __( 'By default we auto-detect image width and fetch a optimal resolution.', 'instagram-feed' ), 'options' => [ 'auto' => __( 'Auto-detect (recommended)', 'instagram-feed' ), 'thumb' => __( 'Thumbnail (150x150)', 'instagram-feed' ), 'medium' => __( 'Medium (320x320)', 'instagram-feed' ), 'full' => __( 'Full size (640x640)', 'instagram-feed' ), ] ] ]; } /** * Get Customize Tab Posts Section * @since 6.0 * @return array */ static function get_nested_caption_controls(){ return [ [ 'type' => 'switcher', 'id' => 'showcaption', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'top' => 15, 'bottom' => 15, 'condition' => ['showcaption' => [true]], #'conditionHide' => true, ], [ 'type' => 'number', 'id' => 'captionlength', 'condition' => ['showcaption' => [true]], #'conditionHide' => true, 'stacked' => 'true', 'fieldSuffix' => 'characters', 'heading' => __( 'Maximum Text Length', 'instagram-feed' ), 'description' => __( 'Caption will truncate after reaching the length', 'instagram-feed' ), ], [ 'type' => 'separator', 'top' => 25, 'bottom' => 15, 'condition' => ['showcaption' => [true]], #'conditionHide' => true, ], [ 'type' => 'heading', 'condition' => ['showcaption' => [true]], #'conditionHide' => true, 'heading' => __( 'Text', 'instagram-feed' ), ], [ 'type' => 'select', 'id' => 'captionsize', 'condition' => ['showcaption' => [true]], #'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Size', 'instagram-feed' ), 'stacked' => 'true', 'style' => ['.sbi_caption_wrap .sbi_caption' => 'font-size:{{value}}px!important;'], 'options' => SBI_Builder_Customizer_Tab::get_text_size_options() ], [ 'type' => 'colorpicker', 'id' => 'captioncolor', 'condition' => ['showcaption' => [true]], #'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Color', 'instagram-feed' ), 'style' => ['.sbi_caption_wrap .sbi_caption' => 'color:{{value}}!important;'], 'stacked' => 'true' ], ]; } /** * Get Customize Tab Posts Section * @since 6.0 * @return array */ static function get_nested_like_comment_summary_controls(){ return [ [ 'type' => 'switcher', 'id' => 'showlikes', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'top' => 15, 'bottom' => 15, 'condition' => ['showlikes' => [true]], #'conditionHide' => true, ], [ 'type' => 'heading', 'condition' => ['showlikes' => [true]], #'conditionHide' => true, 'heading' => __( 'Icon', 'instagram-feed' ), ], [ 'type' => 'select', 'id' => 'likessize', 'condition' => ['showlikes' => [true]], #'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Size', 'instagram-feed' ), 'stacked' => 'true', 'style' => ['.sbi_likes, .sbi_comments, .sbi_likes svg, .sbi_comments svg' => 'font-size:{{value}}px!important;'], 'options' => SBI_Builder_Customizer_Tab::get_text_size_options() ], [ 'type' => 'colorpicker', 'id' => 'likescolor', 'condition' => ['showlikes' => [true]], #'conditionHide' => true, 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Color', 'instagram-feed' ), 'style' => ['.sbi_likes, .sbi_comments' => 'color:{{value}};'], 'stacked' => 'true' ], ]; } /** * Get Customize Tab Posts Section * @since 6.0 * @return array */ static function get_nested_hover_state_controls(){ return [ [ 'type' => 'colorpicker', 'id' => 'hovercolor', 'icon' => 'background', 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Background', 'instagram-feed' ), 'style' => ['.sbi_link' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'hovertextcolor', 'icon' => 'text', 'layout' => 'half', 'strongHeading' => 'false', 'heading' => __( 'Text', 'instagram-feed' ), 'style' => ['.sbi_photo_wrap .sbi_username > a, .sbi_photo_wrap .sbi_caption,.sbi_photo_wrap .sbi_instagram_link,.sbi_photo_wrap .sbi_hover_bottom,.sbi_photo_wrap .sbi_location,.sbi_photo_wrap .sbi_meta,.sbi_photo_wrap .sbi_comments' => 'color:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'heading', 'heading' => __( 'Information to display', 'instagram-feed' ), ], [ 'type' => 'checkboxlist', 'id' => 'hoverdisplay', 'options' => [ [ 'value' => 'username', 'label' => __( 'Username', 'instagram-feed' ), ], [ 'value' => 'date', 'label' => __( 'Date', 'instagram-feed' ), ], [ 'value' => 'instagram', 'label' => __( 'Instagram Icon', 'instagram-feed' ), ], [ 'value' => 'caption', 'label' => __( 'Caption', 'instagram-feed' ), ], [ 'value' => 'likes', 'label' => __( 'Like/Comment Icons
(Business account only)', 'instagram-feed' ), ] ], 'reverse' => 'true', ], ]; } /** * Get Customize Tab Load More Button Section * @since 6.0 * @return array */ static function get_customize_loadmorebutton_controls(){ return [ [ 'type' => 'switcher', 'id' => 'showbutton', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'condition' => ['showbutton' => [true]], 'top' => 20, 'bottom' => 5, ], [ 'type' => 'text', 'id' => 'buttontext', 'condition' => ['showbutton' => [true]], //'conditionHide' => true, 'strongHeading' => 'true', 'heading' => __( 'Text', 'instagram-feed' ), ], [ 'type' => 'separator', 'condition' => ['showbutton' => [true]], 'top' => 15, 'bottom' => 15, ], [ 'type' => 'heading', 'heading' => __( 'Color', 'instagram-feed' ), 'condition' => ['showbutton' => [true]], ], [ 'type' => 'colorpicker', 'id' => 'buttoncolor', 'condition' => ['showbutton' => [true]], 'layout' => 'half', 'icon' => 'background', 'strongHeading' => 'false', 'heading' => __( 'Background', 'instagram-feed' ), 'style' => ['.sbi_load_btn' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'buttonhovercolor', 'condition' => ['showbutton' => [true]], 'layout' => 'half', 'icon' => 'cursor', 'strongHeading' => 'false', 'heading' => __( 'Hover State', 'instagram-feed' ), 'style' => ['.sbi_load_btn:hover' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'buttontextcolor', 'condition' => ['showbutton' => [true]], 'layout' => 'half', 'icon' => 'text', 'strongHeading' => 'false', 'heading' => __( 'Text', 'instagram-feed' ), 'style' => ['.sbi_load_btn' => 'color:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'separator', 'condition' => ['showbutton' => [true]], 'top' => 15, 'bottom' => 5, ], [ 'type' => 'heading', 'heading' => __( 'Advanced', 'instagram-feed' ), 'proLabel' => true, 'checkExtensionPopupLearnMore' => 'postStyling', 'utmLink' => 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=load-more', 'description' => __( 'These properties are available in the PRO version.', 'instagram-feed' ), ], [ 'type' => 'separator', 'condition' => ['showheader' => [true]], 'top' => 30, 'bottom' => 10, ], [ 'type' => 'switcher', 'id' => 'autoscroll', 'condition' => ['showbutton' => [true]], 'switcherTop' => true, 'checkExtensionDimmed' => 'postStyling', 'checkExtensionPopup' => 'postStyling', 'utmLink' => 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=customizer&utm_medium=load-more', //'conditionHide' => true, 'heading' => __( 'Infinite Scroll', 'instagram-feed' ), 'description' => __( 'This will load more posts automatically when the users reach the end of the feed', 'instagram-feed' ), 'stacked' => 'true', 'labelStrong' => 'true', 'layout' => 'half', 'reverse' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'number', 'id' => 'autoscrolldistance', 'condition' => ['showbutton' => [true],'autoscroll' => ['true']], 'conditionHide' => true, 'strongHeading' => false, 'stacked' => 'true', 'layout' => 'half', 'placeholder' => '200', 'child' => true, 'fieldSuffix' => 'px', 'heading' => __( 'Trigger Distance', 'instagram-feed' ), ], ]; } /** * Get Customize Tab Follow Button Section * @since 6.0 * @return array */ static function get_customize_followbutton_controls(){ return [ [ 'type' => 'switcher', 'id' => 'showfollow', 'label' => __( 'Enable', 'instagram-feed' ), 'reverse' => 'true', 'stacked' => 'true', 'options' => [ 'enabled' => true, 'disabled' => false ] ], [ 'type' => 'separator', 'condition' => ['showfollow' => [true]], 'top' => 20, 'bottom' => 5, ], [ 'type' => 'text', 'id' => 'followtext', 'condition' => ['showfollow' => [true]], //'conditionHide' => true, 'strongHeading' => 'true', 'heading' => __( 'Text', 'instagram-feed' ), ], [ 'type' => 'separator', 'condition' => ['showfollow' => [true]], 'top' => 15, 'bottom' => 15, ], [ 'type' => 'heading', 'heading' => __( 'Color', 'instagram-feed' ), 'condition' => ['showfollow' => [true]], ], [ 'type' => 'colorpicker', 'id' => 'followcolor', 'condition' => ['showfollow' => [true]], 'layout' => 'half', 'icon' => 'background', 'strongHeading' => 'false', 'heading' => __( 'Background', 'instagram-feed' ), 'style' => ['.sbi_follow_btn a' => 'background:{{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'followhovercolor', 'condition' => ['showfollow' => [true]], 'layout' => 'half', 'icon' => 'cursor', 'strongHeading' => 'false', 'heading' => __( 'Hover State', 'instagram-feed' ), 'style' => ['.sbi_follow_btn a:hover' => 'box-shadow:inset 0 0 10px 20px {{value}}!important;'], 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'followtextcolor', 'condition' => ['showbutton' => [true]], 'layout' => 'half', 'icon' => 'text', 'strongHeading' => 'false', 'heading' => __( 'Text', 'instagram-feed' ), 'style' => ['.sbi_follow_btn a' => 'color:{{value}}!important;'], 'stacked' => 'true' ] ]; } /** * Get Customize Tab LightBox Section * @since 6.0 * @return array */ static function get_customize_lightbox_controls(){ return [ [ 'type' => 'separator', 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'top' => 40, 'bottom' => 5, ], [ 'type' => 'heading', 'heading' => __( 'Color', 'instagram-feed' ), 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', ], [ 'type' => 'colorpicker', 'id' => 'fakecolorpicker', 'icon' => 'background', 'layout' => 'half', 'strongHeading' => 'false', 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'heading' => __( 'Background', 'instagram-feed' ), 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'fakecolorpicker', 'icon' => 'text', 'layout' => 'half', 'strongHeading' => 'false', 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'heading' => __( 'Text', 'instagram-feed' ), 'stacked' => 'true' ], [ 'type' => 'colorpicker', 'id' => 'fakecolorpicker', 'icon' => 'link', 'layout' => 'half', 'strongHeading' => 'false', 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'heading' => __( 'Link Color', 'instagram-feed' ), 'stacked' => 'true' ], [ 'type' => 'separator', 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'top' => 30, 'bottom' => 10, ], [ 'type' => 'heading', 'heading' => __( 'Comments', 'instagram-feed' ), 'tooltip' => __( 'Display comments for your posts inside the lightbox. Comments are only available for User feeds from Business accounts.', 'instagram-feed' ), 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', ], [ 'type' => 'number', 'id' => 'numcomments', 'condition' => ['disablelightbox' => [false],'lightboxcomments' => [true]], 'checkExtensionDimmed' => 'lightbox', 'checkExtensionPopup' => 'lightbox', 'strongHeading' => false, 'stacked' => 'true', 'placeholder' => '20', 'fieldSuffixAction' => 'clearCommentCache', 'fieldSuffix' => 'Clear Cache', 'heading' => __( 'No. of Comments', 'instagram-feed' ), 'description' => __( 'Clearing cache will remove all the saved comments in the database', 'instagram-feed' ), 'descriptionPosition' => 'bottom' ], ]; } } inc/Builder/SBI_Tooltip_Wizard.php000064400000005400150515074560013072 0ustar00init(); } /** * Initialize class. * * @since 6.0 */ public function init() { /* if ( ! wpforms_is_admin_page( 'builder' ) && ! wp_doing_ajax() && ! $this->is_form_embed_page() ) { return; } */ $this->hooks(); } /** * Register hooks. * * @since 6.0 */ public function hooks() { add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] ); add_action( 'admin_footer', [ $this, 'output' ] ); } /** * Enqueue assets. * * @since 6.0 */ public function enqueues() { wp_enqueue_style( 'sbi_tooltipster', SBI_PLUGIN_URL . 'admin/builder/assets/css/tooltipster.css', null, SBIVER ); wp_enqueue_script( 'sbi_tooltipster', SBI_PLUGIN_URL . 'admin/builder/assets/js/jquery.tooltipster.min.js', [ 'jquery' ], SBIVER, true ); wp_enqueue_script( 'sbi-admin-tooltip-wizard', SBI_PLUGIN_URL . 'admin/builder/assets/js/tooltip-wizard.js', [ 'jquery' ], SBIVER ); $wp_localize_data = []; if( $this->check_gutenberg_wizard() ){ $wp_localize_data['sbi_wizard_gutenberg'] = true; } wp_localize_script( 'sbi-admin-tooltip-wizard', 'sbi_admin_tooltip_wizard', $wp_localize_data ); } /** * Output HTML. * * @since 6.0 */ public function output() { if( $this->check_gutenberg_wizard() ){ $this->gutenberg_tooltip_output(); } } /** * Gutenberg Tooltip Output HTML. * * @since 6.0 */ public function check_gutenberg_wizard() { global $pagenow; return ( ( $pagenow == 'post.php' ) || (get_post_type() == 'page') ) && ! empty( $_GET['sbi_wizard'] ); } /** * Gutenberg Tooltip Output HTML. * * @since 6.0 */ public function gutenberg_tooltip_output() { ?>


get_cache_time(); $content = isset( $m[5] ) ? $m[5] : null; return $m[1] . call_user_func( $shortcode_tags[ $tag ], $attributes, $content, $tag ) . $m[6]; } return $output; } private function get_cache_time() { $schedule = wp_get_schedule( 'sbi_feed_update' ); if($schedule === 'twicedaily') { return 12 * 60; } return 30; } }inc/Services/ServiceContainer.php000064400000000343150515074560013064 0ustar00register(); } }inc/class-sb-instagram-data-manager.php000064400000031030150515074560014044 0ustar00hooks(); } /** * Hook into certain features of the plugin and AJAX calls * * @since 2.9.4/5.12.4 */ public function hooks() { add_action( 'sbi_before_display_instagram', array( $this, 'update_last_used' ) ); add_action( 'sbi_before_display_instagram', array( $this, 'check' ) ); add_action( 'sbi_before_display_instagram', array( $this, 'maybe_update_legacy_sources' ) ); add_action( 'sb_instagram_twicedaily', array( $this, 'maybe_delete_old_data' ) ); } /** * To avoid a database update every page load, the check * is done once a day * * @since 2.9.4/5.12.4 */ public function update_last_used() { $statuses = $this->get_statuses(); // if this hasn't been updated in the last hour if ( $statuses['last_used'] < sbi_get_current_time() - 3600 ) { // update the last used time $statuses['last_used'] = sbi_get_current_time(); $this->update_statuses( $statuses ); } } /** * Check for plain text instagram data in posts table * * @since 2.9.4/5.12.4 */ public function check() { $this->encrypt_json_in_sbi_instagram_posts(); } /** * Updates legacy sources if some are left in the queue from an update */ public function maybe_update_legacy_sources() { if ( \InstagramFeed\Builder\SBI_Source::should_do_source_updates() ) { \InstagramFeed\Builder\SBI_Source::batch_process_legacy_source_queue(); } } /** * Delete unused data after a period * * @return bool * * @since 2.9.4/5.12.4 */ public function maybe_delete_old_data() { global $sb_instagram_posts_manager; $statuses = $this->get_statuses(); $data_was_deleted = false; do_action( 'sbi_before_delete_old_data', $statuses ); if ( $statuses['last_used'] < sbi_get_current_time() - ( 21 * DAY_IN_SECONDS ) ) { $this->delete_caches(); $this->delete_comments_data(); $this->delete_hashtag_data(); $sb_instagram_posts_manager->add_action_log( 'Deleted all platform data.' ); $data_was_deleted = true; } if ( $statuses['last_used'] < sbi_get_current_time() - ( 90 * DAY_IN_SECONDS ) ) { SB_Instagram_Connected_Account::update_connected_accounts( array() ); \InstagramFeed\Builder\SBI_Db::clear_sbi_sources(); global $sb_instagram_posts_manager; $sb_instagram_posts_manager->add_action_log( 'Deleted all connected accounts.' ); $data_was_deleted = true; } return $data_was_deleted; } /** * Delete all data related to hashtags * * @since 2.9.4/5.12.4 */ public function delete_hashtag_data() { global $sb_instagram_posts_manager; $sb_instagram_posts_manager->delete_all_sbi_instagram_posts(); delete_option( 'sbi_top_api_calls' ); delete_option( 'sbi_local_avatars' ); } /** * Delete all non hashtag related data for an account * * @param string $username * * @since 2.9.4/5.12.4 */ public function delete_non_hashtag_sbi_instagram_posts( $username ) { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; $non_hashtag_posts = $wpdb->get_results( "SELECT p.id, p.media_id FROM $table_name as p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id WHERE f.hashtag = '';", ARRAY_A ); $upload = wp_upload_dir(); $file_suffixes = array( 'thumb', 'low', 'full' ); foreach ( $non_hashtag_posts as $post ) { foreach ( $file_suffixes as $file_suffix ) { $file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $post['media_id'] . $file_suffix . '.jpg'; if ( is_file( $file_name ) ) { unlink( $file_name ); } } } $file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg'; if ( is_file( $file_name ) ) { unlink( $file_name ); } $non_hashtag_posts_deleted = $wpdb->query( "DELETE p, f FROM $table_name as p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id WHERE f.hashtag = '';" ); } /** * Delete post data in non-hashtag related posts * * @since 2.9.4/5.12.4 */ public function update_json_non_hashtag_sbi_instagram_posts() { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; $updated = $wpdb->query( "UPDATE $table_name as p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id SET p.json_data = '' WHERE f.hashtag = '';" ); } /** * Encrypt a set of 50 posts if this has been attempted * less than 30 times. * * @since 2.9.4/5.12.4 */ public function encrypt_json_in_sbi_instagram_posts() { $statuses = $this->get_statuses(); // if this hasn't been updated in the last hour if ( $statuses['num_db_updates'] > 30 ) { return; } $statuses['num_db_updates'] = $statuses['num_db_updates'] + 1; $this->update_statuses( $statuses ); global $wpdb; $encryption = new SB_Instagram_Data_Encryption(); $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; $plaintext_posts = $wpdb->get_results( "SELECT * FROM $table_name as p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id WHERE p.json_data LIKE '%{%' ORDER BY p.time_stamp DESC LIMIT 50;", ARRAY_A ); if ( empty( $plaintext_posts ) ) { $statuses['num_db_updates'] = 31; $this->update_statuses( $statuses ); } foreach ( $plaintext_posts as $post ) { $json_data = $encryption->encrypt( $post['json_data'] ); $updated = $wpdb->query( $wpdb->prepare( "UPDATE $table_name as p INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id SET p.json_data = %s WHERE p.id = %d;", $json_data, $post['id'] ) ); } } /** * Delete all comments data * * @since 2.9.4/5.12.4 */ public function delete_comments_data() { /* Comment Cache */ delete_transient( 'sbinst_comment_cache' ); } /** * Delete feed caches * * @param bool $include_backup * * @since 2.9.4/5.12.4 */ public function delete_caches( $include_backup = true ) { /* Backup Caches */ global $wpdb; $table_name = $wpdb->prefix . 'options'; if ( $include_backup ) { $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%!sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%') " ); } /* Regular Caches */ //Delete all transients $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%') " ); delete_option( 'sbi_single_cache' ); \InstagramFeed\Builder\SBI_Db::clear_sbi_feed_caches(); } /** * Update all parts of the database for FB platform guidelines * * @throws Exception * * @since 2.9.4/5.12.4 */ public function update_db_for_dpa() { global $wpdb; $encryption = new SB_Instagram_Data_Encryption(); $table_name = $wpdb->prefix . 'options'; $permanent_caches = $wpdb->get_results( " SELECT * FROM $table_name WHERE option_name LIKE ('%!sbi\_%') ", ARRAY_A ); if ( count( $permanent_caches ) < 10 ) { foreach ( $permanent_caches as $permanent_cache ) { $value = $permanent_cache['option_value']; if ( strpos( $value, '{' ) === 0 ) { $value = $encryption->encrypt( $value ); update_option( $permanent_cache['option_name'], $value, false ); } } $this->delete_caches( false ); } else { $this->delete_caches( true ); } SB_Instagram_Connected_Account::encrypt_all_access_tokens(); $this->encrypt_json_in_sbi_instagram_posts(); $stored_option = get_option( 'sbi_single_cache', array() ); if ( ! is_array( $stored_option ) ) { $stored_option = json_decode( $encryption->decrypt( $stored_option ), true ); } update_option( 'sbi_single_cache', $encryption->encrypt( sbi_json_encode( $stored_option ) ), false ); if ( sbi_is_pro_version() ) { $comment_cache_transient = get_transient( 'sbinst_comment_cache' ); $maybe_decrypted = $encryption->decrypt( $comment_cache_transient ); if ( ! empty( $maybe_decrypted ) ) { $comment_cache_transient = $maybe_decrypted; } $comment_cache = $comment_cache_transient ? json_decode( $comment_cache_transient, true ) : array(); set_transient( 'sbinst_comment_cache', $encryption->encrypt( sbi_json_encode( $comment_cache ) ), 0 ); $ids = get_option( 'sbi_hashtag_ids', array() ); if ( ! is_array( $ids ) ) { $encryption = new SB_Instagram_Data_Encryption(); $ids = json_decode( $encryption->decrypt( $ids ), true ); } update_option( 'sbi_hashtag_ids', $encryption->encrypt( sbi_json_encode( $ids ) ), false ); } } /** * Data manager statuses * * @return array * * @since 2.9.4/5.12.4 */ public function get_statuses() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $return = isset( $sbi_statuses_option['data_manager'] ) ? $sbi_statuses_option['data_manager'] : $this->defaults(); return $return; } /** * Update data manager status * * @param array $statuses * * @since 2.9.4/5.12.4 */ public function update_statuses( $statuses ) { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $sbi_statuses_option['data_manager'] = $statuses; update_option( 'sbi_statuses', $sbi_statuses_option ); } /** * Encrypt using Smash Balloon's support key and salt * * @param string $encrypted_value * * @return bool|string * * @since 2.9.4/5.12.4 */ public function remote_encrypt( $encrypted_value ) { $local_encrypt = new SB_Instagram_Data_Encryption(); $raw_value = $local_encrypt->decrypt( $encrypted_value ); if ( $this->key_salt === null ) { $url = 'https://secure.smashballoon.com/'; $args = array( 'timeout' => 20, ); $response = wp_remote_get( $url, $args ); if ( ! is_wp_error( $response ) ) { $this->key_salt = $response['body']; } } $key = substr( $this->key_salt, 0, 64 ); $salt = substr( $this->key_salt, 64, 64 ); $args = array( 'key' => $key, 'salt' => $salt, ); $remote_encrypt = new SB_Instagram_Data_Encryption( $args ); return $remote_encrypt->encrypt( $raw_value ); } public function remote_decrypt( $encrypted_value ) { if ( $this->key_salt === null ) { $url = 'https://secure.smashballoon.com/'; $args = array( 'timeout' => 20, ); $response = wp_remote_get( $url, $args ); if ( ! is_wp_error( $response ) ) { $this->key_salt = $response['body']; } } $key = substr( $this->key_salt, 0, 64 ); $salt = substr( $this->key_salt, 64, 64 ); $args = array( 'key' => $key, 'salt' => $salt, ); $remote_encrypt = new SB_Instagram_Data_Encryption( $args ); return $remote_encrypt->decrypt( $encrypted_value ); } /** * Reset the data manager * * @since 2.9.4/5.12.4 */ public function reset() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $sbi_statuses_option['data_manager'] = $this->defaults(); update_option( 'sbi_statuses', $sbi_statuses_option ); update_option( 'sbi_db_version', 1.9 ); } /** * Default values for manager * * @return array * * @since 2.9.4/5.12.4 */ public function defaults() { return array( 'last_used' => sbi_get_current_time() - DAY_IN_SECONDS, 'num_db_updates' => 0, ); } } inc/Email_Notification.php000064400000003500150515074560011571 0ustar00'; $header_from = "From: " . $email_from; $headers = array( 'Content-Type: text/html; charset=utf-8', $header_from ); $header_image = SBI_PLUGIN_URL . 'img/balloon-120.png'; $footer_link = admin_url('admin.php?page=sbi-settings&view=advanced&flag=emails'); $message_content = '
' . $bold . '
' . $details; include_once SBI_PLUGIN_DIR . 'inc/class-sb-instagram-education.php'; $educator = new SB_Instagram_Education(); $dyk_message = $educator->dyk_display(); ob_start(); include SBI_PLUGIN_DIR . 'inc/email.php'; $email_body = ob_get_contents(); ob_get_clean(); return wp_mail( $valid_emails, $title, $email_body, $headers ); } }inc/class-sb-instagram-data-encryption.php000064400000010274150515074560014633 0ustar00key = $remote['key']; $this->salt = $remote['salt']; } else { $this->key = $this->get_default_key(); $this->salt = $this->get_default_salt(); } } /** * Encrypts a value. * * If a user-based key is set, that key is used. Otherwise the default key is used. * * @since 2.9.4/5.12.4 * * @param string $value Value to encrypt. * @return string|bool Encrypted value, or false on failure. */ public function encrypt( $value ) { if ( ! sbi_doing_openssl() ) { return $value; } $method = 'aes-256-ctr'; $ivlen = openssl_cipher_iv_length( $method ); $iv = openssl_random_pseudo_bytes( $ivlen ); $raw_value = openssl_encrypt( $value . $this->salt, $method, $this->key, 0, $iv ); if ( ! $raw_value ) { return false; } return base64_encode( $iv . $raw_value ); } /** * Decrypts a value. * * If a user-based key is set, that key is used. Otherwise the default key is used. * * @since 2.9.4/5.12.4 * * @param string $raw_value Value to decrypt. * @return string|bool Decrypted value, or false on failure. */ public function decrypt( $raw_value ) { if ( ! sbi_doing_openssl() ) { return $raw_value; } $raw_value = base64_decode( $raw_value, true ); $method = 'aes-256-ctr'; $ivlen = openssl_cipher_iv_length( $method ); $iv = substr( $raw_value, 0, $ivlen ); $raw_value = substr( $raw_value, $ivlen ); $value = openssl_decrypt( $raw_value, $method, $this->key, 0, $iv ); if ( ! $value || substr( $value, - strlen( $this->salt ) ) !== $this->salt ) { return false; } return substr( $value, 0, - strlen( $this->salt ) ); } /** * Encrypts a value that may already be encrypted. * * If a user-based key is set, that key is used. Otherwise the default key is used. * * @since 6.0 * * @param string $raw_value Value to encrypt. * @return string|bool encrypted value, or false on failure. */ public function maybe_encrypt( $raw_value ) { $maybe_decrypted = $this->decrypt( $raw_value ); if ( $maybe_decrypted ) { return $this->encrypt( $maybe_decrypted ); } return $this->encrypt( $raw_value ); } /** * Uses a raw value and attempts to decrypt it * * @since 6.0.8 * * @param $value * @return bool|string */ public function maybe_decrypt( $value ) { if ( ! is_string( $value ) ) { return $value; } if ( strpos( $value, '{' ) === 0 ) { return $value; } $decrypted = $this->decrypt( $value ); if ( ! $decrypted ) { return $value; } return $decrypted; } /** * Gets the default encryption key to use. * * @since 2.9.4/5.12.4 * * @return string Default (not user-based) encryption key. */ private function get_default_key() { if ( defined( 'SBI_ENCRYPTION_KEY' ) && '' !== SBI_ENCRYPTION_KEY ) { return SBI_ENCRYPTION_KEY; } if ( defined( 'LOGGED_IN_KEY' ) && '' !== LOGGED_IN_KEY ) { return LOGGED_IN_KEY; } // If this is reached, you're either not on a live site or have a serious security issue. return 'das-ist-kein-geheimer-schluessel'; } /** * Gets the default encryption salt to use. * * @since 2.9.4/5.12.4 * * @return string Encryption salt. */ private function get_default_salt() { if ( defined( 'SBI_ENCRYPTION_SALT' ) && '' !== SBI_ENCRYPTION_SALT ) { return SBI_ENCRYPTION_SALT; } if ( defined( 'LOGGED_IN_SALT' ) && '' !== LOGGED_IN_SALT ) { return LOGGED_IN_SALT; } // If this is reached, you're either not on a live site or have a serious security issue. return 'das-ist-kein-geheimes-salz'; } } inc/class-sb-instagram-posts-manager.php000064400000117741150515074560014321 0ustar00sbi_options = get_option( 'sb_instagram_settings' ); $this->errors = get_option( 'sb_instagram_errors', array() ); if ( ! isset( $this->errors['connection'] ) ) { $this->errors = array( 'connection' => array(), 'hashtag' => array(), 'resizing' => array(), 'database_create' => array(), 'upload_dir' => array(), 'accounts' => array(), 'error_log' => array(), 'action_log' => array(), 'revoked' => array(), ); } $this->display_error = array(); if ( $this->does_resizing_tables_exist() ) { $this->resizing_tables_exist = true; } require_once( trailingslashit( dirname( __FILE__ ) ) . '/Platform_Data.php' ); $platform_data_manager = new \InstagramFeed\Platform_Data(); $platform_data_manager->register_hooks(); } /** * Stores information about an encountered error related to a connected account * * @param $connected_account array * @param $error_type string * @param $details mixed/array/string * * @since 2.7/5.10 */ public function add_connected_account_error( $connected_account, $error_type, $details ) { $account_id = $connected_account['user_id']; $this->errors['accounts'][ $account_id ][ $error_type ] = $details; if ( $error_type === 'api' ) { $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 3; } if ( isset( $details['error']['code'] ) && (int) $details['error']['code'] === 18 ) { $this->errors['accounts'][ $account_id ][ $error_type ]['clear_time'] = time() + 60 * 15; } \InstagramFeed\Builder\SBI_Source::add_error( $account_id, $details ); } /** * Stores errors so they can be retrieved and explained to users * in messages as well as temporarily disable certain features * * @param string $type * @param array $details * @param mixed/bool/array $connected_account_term * * @since 2.7/5.10 */ public function add_error( $type, $details, $connected_account_term = false ) { $connected_account = false; $log_item = date( 'm-d H:i:s' ) . ' - '; if ( $connected_account_term ) { if ( ! is_array( $connected_account_term ) ) { $connected_account = SB_Instagram_Connected_Account::lookup( $connected_account_term ); } else { $connected_account = $connected_account_term; } $this->add_connected_account_error( $connected_account, $type, $details ); } // is it connection? or what type? if ( $type === 'api' || $type === 'wp_remote_get' ) { $connection_details = array( 'error_id' => '', ); $connection_details['critical'] = false; if ( isset( $details['error']['code'] ) ) { $connection_details['error_id'] = $details['error']['code']; if ( $this->is_critical_error( $details ) ) { $connection_details['critical'] = true; } if ( $this->is_app_permission_related( $details ) ) { if ( ! in_array( $connected_account['user_id'], $this->errors['revoked'], true ) ) { $this->errors['revoked'][] = $connected_account['user_id']; } /** * Fires when an app permission related error is encountered * * @param array $connected_account The connected account that encountered the error * * @since 6.0.6 */ do_action( 'sbi_app_permission_revoked', $connected_account ); } } elseif ( isset( $details['response'] ) && is_wp_error( $details['response'] ) ) { foreach ( $details['response']->errors as $key => $item ) { $connection_details['error_id'] = $key; } $connection_details['critical'] = true; } if ( get_the_ID() !== 0 ) { $connection_details['post_id'] = get_the_ID(); } $connection_details['error_message'] = $this->generate_error_message( $details, $connected_account ); $log_item .= $connection_details['error_message']['admin_only']; $this->maybe_set_display_error( 'connection', $connection_details ); $this->errors['connection'] = $connection_details; } if ( $type === 'hashtag' ) { $hashtag_details = array( 'error_id' => '', 'hashtag' => isset( $details['hashtag'] ) ? $details['hashtag'] : '', ); if ( isset( $details['error']['code'] ) ) { if ( (int) $details['error']['code'] === 24 ) { $hashtag_details['clear_time'] = time() + 60 * 5; } } if ( isset( $details['error']['code'] ) ) { $hashtag_details['error_id'] = $details['error']['code']; } elseif ( isset( $details['response'] ) && is_wp_error( $details['response'] ) ) { foreach ( $details['response']->errors as $key => $item ) { $hashtag_details['error_id'] = $key; } } if ( get_the_ID() !== 0 ) { $hashtag_details['post_id'] = get_the_ID(); } $hashtag_details['error_message'] = $this->generate_error_message( $details, $connected_account ); $log_item .= $hashtag_details['error_message']['admin_only']; $this->maybe_set_display_error( 'hashtag', $hashtag_details ); $found = false; if ( isset( $details['hashtag'] ) ) { foreach ( $this->errors['hashtag'] as $hashtag_error_item ) { if ( isset( $hashtag_error_item['hashtag'] ) && strtolower( $hashtag_error_item['hashtag'] ) === strtolower( $details['hashtag'] ) && $hashtag_error_item['error_id'] === $details['error_id'] ) { $found = true; } } } if ( ! $found ) { $this->errors['hashtag'][] = $hashtag_details; } } if ( $type === 'image_editor' || $type === 'storage' ) { $this->errors['resizing'] = $details; $log_item .= $details; } if ( $type === 'database_create' ) { $this->errors['database_create'] = $details; $log_item .= $details; } if ( $type === 'upload_dir' ) { $this->errors['upload_dir'] = $details; $log_item .= $details; } if ( $type === 'unused_feed' ) { $this->errors['unused_feed'] = $details; $log_item .= $details; } if ( $type === 'platform_data_deleted' ) { $this->errors['platform_data_deleted'] = $details; $log_item .= $details; } $current_log = $this->errors['error_log']; if ( is_array( $current_log ) && count( $current_log ) >= 10 ) { reset( $current_log ); unset( $current_log[ key( $current_log ) ] ); } $current_log[] = $log_item; $this->errors['error_log'] = $current_log; update_option( 'sb_instagram_errors', $this->errors, false ); } /** * Stores a time stamped string of information about * actions that might lead to correcting an error * * @param string $log_item * * @since 2.7/5.10 */ public function add_action_log( $log_item ) { $current_log = $this->errors['action_log']; if ( is_array( $current_log ) && count( $current_log ) >= 10 ) { reset( $current_log ); unset( $current_log[ key( $current_log ) ] ); } $current_log[] = date( 'm-d H:i:s' ) . ' - ' . $log_item; $this->errors['action_log'] = $current_log; update_option( 'sb_instagram_errors', $this->errors, false ); } /** * @return mixed * * @since 2.7/5.10 */ public function get_error_log() { return $this->errors['error_log']; } /** * @return mixed * * @since 2.7/5.10 */ public function get_action_log() { return $this->errors['action_log']; } /** * Certain API errors are considered critical and will trigger * the various notifications to users to correct them. * * @param $details * * @return bool * * @since 2.7/5.10 */ public function is_critical_error( $details ) { $error_code = (int) $details['error']['code']; $critical_codes = array( 803, // ID doesn't exist 100, // access token or permissions 190, // access token or permissions 10, // app permissions or scopes ); return in_array( $error_code, $critical_codes, true ); } /** * Should clear platform data * * @param $details * * @return bool * * @since 2.7/5.10 */ public function is_app_permission_related( $details ) { $error_code = (int) $details['error']['code']; $error_subcode = isset( $details['error']['error_subcode'] ) ? (int) $details['error']['error_subcode'] : 0; $critical_codes = array( 190, // access token or permissions ); $critical_subcodes = array( 458, // access token or permissions ); if ( in_array( $error_code, $critical_codes, true ) ) { if ( strpos( $details['error']['message'], 'user has not authorized application' ) !== false ) { return true; } return in_array( $error_subcode, $critical_subcodes, true ); } return false; } /** * Creates an array of information for easy display of API errors * * @param $response * @param array $connected_account * * @return array * * @since 2.7/5.10 */ public function generate_error_message( $response, $connected_account = array( 'username' => '' ) ) { $error_message_return = array( 'error_message' => '', 'admin_only' => '', 'frontend_directions' => '', 'backend_directions' => '', 'time' => time(), ); $hash = isset( $response['error']['code'] ) ? '#' . (int) $response['error']['code'] : ''; if ( isset( $response['response'] ) && is_wp_error( $response['response'] ) ) { $error_message_return['error_message'] = __( 'HTTP Error. Unable to connect to the Instagram API.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' ); $error_message_return['admin_only'] = sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] ); $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) { $num = count( $response['response']->errors ); $i = 1; foreach ( $response['response']->errors as $key => $item ) { $error_message_return['admin_only'] .= ' ' . $key . ' - ' . $item[0]; if ( $i < $num ) { $error_message_return['admin_only'] .= ','; } $num++; } } return $error_message_return; } $hash = '#' . (int) $response['error']['code']; $link = admin_url( 'admin.php?page=sbi-settings' ); if ( isset( $response['error']['message'] ) ) { if ( (int) $response['error']['code'] === 100 ) { $error_message_return['error_message'] = __( 'Error: Access Token is not valid or has expired.', 'instagram-feed' ) . ' ' . __( 'Feed will not update.', 'instagram-feed' ); $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message']; $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; } elseif ( (int) $response['error']['code'] === 18 ) { $error_message_return['error_message'] = __( 'Error: Hashtag limit of 30 unique hashtags per week has been reached.', 'instagram-feed' ); $error_message_return['admin_only'] = __( 'If you need to display more than 30 hashtag feeds on your site, consider connecting an additional business account from a separate Instagram Identity and Facebook page. Connecting an additional Instagram business account from the same Facebook page will not raise the limit.', 'instagram-feed' ); $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; } elseif ( (int) $response['error']['code'] === 10 ) { $error_message_return['error_message'] = sprintf( __( 'Error: Connected account for the user %s does not have permission to use this feed type.', 'instagram-feed' ), $connected_account['username'] ); $error_message_return['admin_only'] = __( 'Try using the big blue button on the "Configure" tab to reconnect the account and update its permissions.', 'instagram-feed' ); $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; } elseif ( (int) $response['error']['code'] === 24 ) { $error_message_return['error_message'] = __( 'Error: Cannot retrieve posts for this hashtag.', 'instagram-feed' ); $error_message_return['admin_only'] = $response['error']['error_user_msg']; $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; } else { $error_message_return['error_message'] = __( 'There has been a problem with your Instagram Feed.', 'instagram-feed' ); $error_message_return['admin_only'] = sprintf( __( 'API error %s:', 'instagram-feed' ), $response['error']['code'] ) . ' ' . $response['error']['message']; $error_message_return['frontend_directions'] = '' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . ''; } } else { $error_message_return['error_message'] = __( 'An unknown error has occurred.', 'instagram-feed' ); $error_message_return['admin_only'] = json_encode( $response ); } return $error_message_return; } /** * Display errors are saved with the feed cache so they will still be displayed * on the frontend * * @param string $type * @param array $error * * @since 2.7/5.10 */ public function maybe_set_display_error( $type, $error ) { if ( $type === 'connection' ) { if ( empty( $this->display_error['connection'] ) ) { $this->display_error['connection'] = $error; } } elseif ( $type === 'configuration' ) { if ( empty( $this->display_error['configuration'] ) ) { $this->display_error['configuration'] = $error; } } elseif ( $type === 'hashtag' ) { $this->display_error['hashtag'][] = $error; } elseif ( $type === 'hashtag_limit' ) { if ( empty( $this->display_error['connection'] ) ) { $this->display_error['hashtag_limit'] = $error; } } } /** * @param string $type * * @since 2.7/5.10 */ public function maybe_remove_display_error( $type ) { if ( isset( $this->display_error[ $type ] ) ) { unset( $this->display_error[ $type ] ); } } /** * The plugin has a limit on how many post records can be stored and * images resized to avoid overloading servers. This function deletes the post that * has the longest time passed since it was retrieved. * * @since 2.0/4.0 */ public function delete_least_used_image() { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS ); $max = isset( $this->limit ) && $this->limit > 1 ? $this->limit : 1; $oldest_posts = $wpdb->get_results( "SELECT id, media_id FROM $table_name ORDER BY last_requested ASC LIMIT $max", ARRAY_A ); $upload = wp_upload_dir(); $file_suffixes = array( 'thumb', 'low', 'full' ); foreach ( $oldest_posts as $post ) { foreach ( $file_suffixes as $file_suffix ) { $file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $post['media_id'] . $file_suffix . '.jpg'; if ( is_file( $file_name ) ) { unlink( $file_name ); } } $wpdb->query( $wpdb->prepare( "DELETE FROM $table_name WHERE id = %d", $post['id'] ) ); $wpdb->query( $wpdb->prepare( "DELETE FROM $feeds_posts_table_name WHERE record_id = %d", $post['id'] ) ); } } /** * Calculates how many records are in the database and whether or not it exceeds the limit * * @return bool * * @since 2.0/4.0 */ public function max_total_records_reached() { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $num_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" ); if ( ! isset( $this->limit ) && (int) $num_records > SBI_MAX_RECORDS ) { $this->limit = (int) $num_records - SBI_MAX_RECORDS; } return ( (int) $num_records > SBI_MAX_RECORDS ); } /** * The plugin caps how many new images are created in a 15 minute window to * avoid overloading servers * * @return bool * * @since 2.0/4.0 */ public function max_resizing_per_time_period_reached() { global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $fifteen_minutes_ago = date( 'Y-m-d H:i:s', time() - 15 * 60 ); $num_new_records = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name WHERE created_on > '$fifteen_minutes_ago'" ); return ( (int) $num_new_records > 100 ); } /** * @return bool * * @since 2.0/4.0 */ public function image_resizing_disabled( $data = false ) { $options = sbi_get_database_settings(); $disable_resizing = isset( $options['sb_instagram_disable_resize'] ) ? $options['sb_instagram_disable_resize'] === 'on' || $options['sb_instagram_disable_resize'] === true : false; $disable_resizing = apply_filters( 'sbi_image_resizing_disabled', $disable_resizing, $data ); if ( ! $disable_resizing ) { $disable_resizing = isset( $this->resizing_tables_exist ) ? ! $this->resizing_tables_exist : ! $this->does_resizing_tables_exist(); } return $disable_resizing; } /** * Used to skip image resizing if the tables were never successfully * created * * @return bool * * @since 2.0/5.0 */ public function does_resizing_tables_exist() { global $wpdb; $table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS ); $resizing_key = 'sbi_resizing_exists'; $sbi_resizing_cache = wp_cache_get( $resizing_key ); if ( false === $sbi_resizing_cache ) { if ( $wpdb->get_var( "show tables like '$table_name'" ) == $table_name ) { wp_cache_set( $resizing_key, true ); } else { wp_cache_set( $resizing_key, false ); } } return $sbi_resizing_cache; } /** * Resets the custom tables and deletes all image files * * @since 2.0/4.0 */ public function delete_all_sbi_instagram_posts() { $upload = wp_upload_dir(); global $wpdb; $posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . '*' ); // get all file names foreach ( $image_files as $file ) { // iterate files if ( is_file( $file ) ) { unlink( $file ); } } $connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts(); foreach ( $connected_accounts as $account_id => $data ) { if ( isset( $data['local_avatar'] ) ) { unset( $connected_accounts[ $account_id ]['local_avatar'] ); } } $options['connected_accounts'] = $connected_accounts; update_option( 'sb_instagram_settings', $options ); //Delete tables $wpdb->query( "DROP TABLE IF EXISTS $posts_table_name" ); $feeds_posts_table_name = esc_sql( $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS ); $wpdb->query( "DROP TABLE IF EXISTS $feeds_posts_table_name" ); $table_name = $wpdb->prefix . 'options'; $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%') " ); $wpdb->query( " DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%') " ); delete_option( 'sbi_hashtag_ids' ); delete_option( 'sbi_local_avatars' ); $upload = wp_upload_dir(); $upload_dir = $upload['basedir']; $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME; if ( ! file_exists( $upload_dir ) ) { $created = wp_mkdir_p( $upload_dir ); if ( $created ) { $this->remove_error( 'upload_dir' ); } else { $this->add_error( 'upload_dir', __( 'There was an error creating the folder for storing resized images.', 'instagram-feed' ) . ' ' . $upload_dir ); } } else { $this->remove_error( 'upload_dir' ); } sbi_create_database_table(); } /** * Whether or not the one time request to the "top posts" endpoint for the hashtag * was made * * @param string $hashtag * * @return bool */ public static function top_post_request_already_made( $hashtag ) { $list_of_top_hashtags = get_option( 'sbi_top_api_calls', array() ); return in_array( $hashtag, $list_of_top_hashtags, true ); } /** * @param $hashtag */ public static function maybe_update_list_of_top_hashtags( $hashtag ) { $list_of_top_hashtags = get_option( 'sbi_top_api_calls', array() ); if ( ! in_array( $hashtag, $list_of_top_hashtags, true ) ) { $list_of_top_hashtags[] = $hashtag; update_option( 'sbi_top_api_calls', $list_of_top_hashtags ); } } /** * @return array * * @since 2.0/4.0 */ public function get_errors() { return $this->errors; } /** * @param string $type * @param mixed/array/bool $connected_account * * @since 2.0/4.0 */ public function remove_error( $type, $connected_account = false ) { $update = false; if ( ! empty( $this->errors[ $type ] ) ) { $this->errors[ $type ] = array(); $this->add_action_log( 'Cleared ' . $type . ' error.' ); $update = true; } if ( ! empty( $connected_account ) ) { if ( $this->remove_connected_account_error( $connected_account, $type, false ) ) { $this->add_action_log( 'Cleared connected account error ' . $connected_account['username'] . '.' ); } if ( $type === 'connection' ) { if ( $this->remove_connected_account_error( $connected_account, 'api', false ) ) { $this->add_action_log( 'Cleared connected account error ' . $connected_account['username'] . '.' ); } } if ( ! empty( $this->errors['revoked'] ) ) { if ( ( $key = array_search( $connected_account['user_id'], $this->errors['revoked'] ) ) !== false ) { unset( $this->errors['revoked'][ $key ] ); } } $update = true; } if ( $update ) { update_option( 'sb_instagram_errors', $this->errors, false ); } } /** * @param array $clearing_account * @param string $clearing_error_type * @param bool $update * * @return bool * * @since 2.7/5.10 */ public function remove_connected_account_error( $clearing_account, $clearing_error_type = 'all', $update = true ) { $cleared = false; if ( isset( $this->errors['accounts'] ) ) { if ( ! isset( $clearing_account['user_id'] ) ) { return $cleared; } $clearing_account_id = $clearing_account['user_id']; foreach ( $this->errors['accounts'] as $account_id => $error_types ) { if ( ! SB_Instagram_Connected_Account::lookup( $account_id ) ) { unset( $this->errors['accounts'][ $account_id ] ); } else { foreach ( $error_types as $error_type => $details ) { if ( (string) $account_id === (string) $clearing_account_id ) { if ( $error_type === $clearing_error_type || $clearing_error_type === 'all' ) { unset( $this->errors['accounts'][ $account_id ][ $error_type ] ); $cleared = true; } } else { if ( isset( $details['username'] ) ) { if ( $details['username'] === $clearing_account['username'] ) { if ( $error_type === $clearing_error_type || $clearing_error_type === 'all' ) { unset( $this->errors['accounts'][ $account_id ][ $error_type ] ); $cleared = true; } } } if ( isset( $this->errors['accounts'][ $account_id ] ) && isset( $details['access_token'] ) ) { if ( $details['access_token'] === $clearing_account['access_token'] ) { if ( $error_type === $clearing_error_type || $clearing_error_type === 'all' ) { unset( $this->errors['accounts'][ $account_id ][ $error_type ] ); $cleared = true; } } } } } if ( empty( $this->errors['accounts'][ $account_id ] ) ) { unset( $this->errors['accounts'][ $account_id ] ); } } } if ( $update ) { update_option( 'sb_instagram_errors', $this->errors, false ); } } return $cleared; } /** * * @since 2.7/5.10 */ public function remove_all_errors() { delete_option( 'sb_instagram_errors' ); sb_instagram_cron_clear_cache(); } /** * When an account is used to make a successful connection * * @since 2.7/5.10 */ public function reset_api_errors() { $this->errors['connection'] = array(); $this->errors['accounts'] = array(); update_option( 'sb_instagram_errors', $this->errors, false ); sb_instagram_cron_clear_cache(); } /** * @deprecated */ public function update_error_page( $id ) { if ( $id !== 0 ) { update_option( 'sb_instagram_error_page', $id, false ); } } /** * @return bool * * @since 2.7/5.10 */ public function get_error_page() { if ( isset( $this->errors['connection']['post_id'] ) ) { return $this->errors['connection']['post_id']; } return false; } /** * @return array * * @since 2.0/5.0 */ public function get_frontend_errors( $instagram_feed = false ) { if ( $instagram_feed ) { $cached_errors = $instagram_feed->get_cached_feed_error(); if ( ! empty( $cached_errors ) ) { return $cached_errors; } } $error_messages = array(); if ( ! empty( $this->display_error['connection']['error_message'] ) ) { $error_messages[] = $this->display_error['connection']['error_message']; } if ( ! empty( $this->display_error['configuration'] ) ) { $error_messages[] = $this->display_error['configuration']; } if ( ! empty( $this->display_error['hashtag'][0] ) ) { $error_24 = array(); $error_24_message = array(); foreach ( $this->display_error['hashtag'] as $hashtag_error ) { if ( $hashtag_error['error_id'] === 24 ) { if ( ! in_array( $hashtag_error['hashtag'], $error_24, true ) ) { $error_24[] = $hashtag_error['hashtag']; } if ( empty( $error_24_message ) ) { $error_24_message = $hashtag_error['error_message']; $error_24_message['admin_only'] = str_replace( $hashtag_error['hashtag'], '###', $error_24_message['admin_only'] ); } } else { $error_messages[] = $hashtag_error['error_message']; } } if ( ! empty( $error_24_message ) ) { $hashtag_string = count( $error_24 ) > 1 ? implode( '", "', $error_24 ) : $error_24[0]; $error_24_message['admin_only'] = str_replace( '###', $hashtag_string, $error_24_message['admin_only'] ); $error_messages[] = $error_24_message; } } if ( ! empty( $this->display_error['hashtag_limit'] ) ) { $response = array( 'error' => $this->display_error['hashtag_limit']['error'], ); $error_messages[] = $this->generate_error_message( $response ); } return $error_messages; } /** * @param $account * * @return bool * * @since 2.7/5.10 */ public function account_over_hashtag_limit( $account ) { if ( ! isset( $this->errors['accounts'][ $account['user_id'] ] ) ) { return false; } if ( isset( $this->errors['accounts'][ $account['user_id'] ]['hashtag_limit'] ) ) { if ( $this->errors['accounts'][ $account['user_id'] ]['hashtag_limit']['clear_time'] < time() ) { $this->remove_connected_account_error( $account, 'hashtag_limit', true ); return false; } else { $this->maybe_set_display_error( 'hashtag_limit', $this->errors['accounts'][ $account['user_id'] ]['hashtag_limit'] ); return true; } } return false; } /** * @param $connected_account * * @return bool * * @since 2.7/5.10 */ public function connected_account_has_error( $connected_account ) { if ( ! isset( $connected_account['user_id'] ) ) { return false; } if ( empty( $this->errors['accounts'] ) ) { return false; } $account_id = $connected_account['user_id']; if ( ! empty( $this->errors['accounts'][ $account_id ] ) ) { foreach ( $this->errors['accounts'][ $account_id ] as $error_key => $error_info ) { if ( strpos( $error_key, 'hashtag' ) === false ) { if ( $this->is_critical_error( $error_info ) ) { return true; } } } } return false; } /** * Whether or not the hashtag is unvailable in the API for some reason * * @param $hashtag * * @return bool * * @since 2.7/5.10 */ public function hashtag_has_error( $hashtag ) { if ( ! isset( $this->errors['hashtag'][0] ) ) { return false; } $to_save = array(); $changed = false; $return = false; foreach ( $this->errors['hashtag'] as $hashtag_error ) { if ( ! empty( $hashtag_error['hashtag'] ) && strtolower( $hashtag_error['hashtag'] ) === strtolower( $hashtag ) ) { if ( ! empty( $hashtag_error['clear_time'] ) ) { if ( $hashtag_error['clear_time'] < time() ) { $changed = true; $return = false; // clear the error, return false } else { $to_save[] = $hashtag_error; $this->maybe_set_display_error( 'hashtag', $hashtag_error ); $return = true; } } } else { if ( ! empty( $hashtag_error['clear_time'] ) ) { if ( $hashtag_error['clear_time'] < time() ) { $changed = true; } else { $to_save[] = $hashtag_error; } } else { $to_save[] = $hashtag_error; } } } if ( $changed ) { $this->errors['hashtag'] = $to_save; update_option( 'sb_instagram_errors', $this->errors, false ); } return $return; } /** * Only some errors should cause the user to be notified using email and site health * * @return string */ public function get_critical_errors() { if ( ! $this->are_critical_errors() ) { return ''; } $accounts_revoked_string = ''; $accounts_revoked = ''; if ( $this->was_app_permission_related_error() ) { $accounts_revoked = $this->get_app_permission_related_error_ids(); if ( count( $accounts_revoked ) > 1 ) { $accounts_revoked = implode( ', ', $accounts_revoked ); } else { $accounts_revoked = $accounts_revoked[0]; } $accounts_revoked_string = sprintf( __( 'Instagram Feed related data for the account(s) %s was removed due to permission for the Smash Balloon App on Facebook or Instagram being revoked.

To prevent the automated data deletion for the account, please reconnect your account within 7 days.', 'instagram-feed' ), $accounts_revoked ); } if ( isset( $this->errors['connection']['critical'] ) ) { $errors = $this->get_errors(); $error_message = ''; if ( $errors['connection']['error_id'] === 190 ) { $error_message .= '' . __( 'Action Required Within 7 Days', 'instagram-feed' ) . '
'; $error_message .= __( 'An account admin has deauthorized the Smash Balloon app used to power the Instagram Feed plugin.', 'instagram-feed' ); $error_message .= ' ' . sprintf( __( 'If the Instagram source is not reconnected within 7 days then all Instagram data will be automatically deleted on your website for this account (ID: %s) due to Facebook data privacy rules.', 'instagram-feed' ), $accounts_revoked ); $error_message .= __( '

To prevent the automated data deletion for the source, please reconnect your source within 7 days.', 'instagram-feed' ); $error_message .= '

' . __( 'More Information', 'instagram-feed' ) . ''; } else { $error_message_array = $errors['connection']['error_message']; $error_message .= '' . $error_message_array['error_message'] . '
'; $error_message .= $error_message_array['admin_only'] . '

'; if ( ! empty( $accounts_revoked_string ) ) { $error_message .= $accounts_revoked_string . '

'; } if ( ! empty( $error_message_array['backend_directions'] ) ) { $error_message .= $error_message_array['backend_directions']; } else { $retry = ''; if ( is_admin() ) { $retry = ''; } $hash = isset( $errors['connection']['error_id'] ) ? '#' . (int) $errors['connection']['error_id'] : ''; $error_message .= '

' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '' . $retry. '

'; } } } else { $connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts(); foreach ( $connected_accounts as $connected_account ) { if ( isset( $connected_account['private'] ) && sbi_private_account_near_expiration( $connected_account ) ) { $link_1 = ''; $link_2 = ''; $error_message_array = array( 'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ), 'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %1$smake your Instagram account public%2$s.', 'instagram-feed' ), $link_1, $link_2 ), 'frontend_directions' => '' . __( 'Click here to troubleshoot', 'instagram-feed' ) . '', 'backend_directions' => '', ); } if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) { if ( isset( $this->errors['accounts'][ $connected_account['user_id'] ]['api']['error'] ) ) { if ( $this->is_critical_error( $this->errors['accounts'][ $connected_account['user_id'] ]['api'] ) ) { $error_message_array = $this->generate_error_message( $this->errors['accounts'][ $connected_account['user_id'] ]['api'], $connected_account ); } } } if ( ! isset( $error_message ) && isset( $error_message_array ) ) { $error_message = $error_message_array['admin_only'] . '

'; if ( ! empty( $error_message_array['backend_directions'] ) ) { $error_message .= $error_message_array['backend_directions']; } else { $retry = ''; if ( is_admin() ) { $retry = ''; } $error_message .= '

' . __( 'Directions on how to resolve this issue', 'instagram-feed' ) . '' . $retry. '

'; } } } } if ( isset( $error_message ) ) { $error_message = str_replace( 'Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api', '', $error_message ); } else { $error_message = ''; } // remove link to FB docs return $error_message; } /** * @since 2.0/5.0 */ public function reset_frontend_errors() { $this->display_error = array(); } /** * Remove all API request delays, triggered after saving settings * * @since 2.7/5.10 */ public function clear_api_request_delays() { if ( empty( $this->errors['accounts'] ) && empty( $this->errors['hashtag'] ) ) { return; } $changed = false; foreach ( $this->errors['accounts'] as $account_id => $account_error ) { if ( ! empty( $account_error['api']['clear_time'] ) ) { $this->errors['accounts'][ $account_id ]['api']['clear_time'] = 0; } $changed = true; } foreach ( $this->errors['hashtag'] as $key => $hashtag_error ) { if ( ! empty( $hashtag_error['hashtag'] ) ) { if ( ! empty( $hashtag_error['clear_time'] ) ) { $this->errors['hashtag'][ $key ]['clear_time'] = 0; $changed = true; } } } if ( $changed ) { update_option( 'sb_instagram_errors', $this->errors, false ); } } /** * @since 2.0/5.1.2 */ public function are_current_api_request_delays( $connected_account ) { if ( empty( $this->errors['accounts'] ) ) { return false; } $account_id = $connected_account['user_id']; $is_delay = false; if ( isset( $this->errors['accounts'][ $account_id ]['api'] ) ) { if ( ! empty( $this->errors['accounts'][ $account_id ]['api']['clear_time'] ) ) { if ( $this->errors['accounts'][ $account_id ]['api']['clear_time'] < time() ) { $is_delay = false; return apply_filters( 'sbi_is_api_delay', $is_delay ); } else { $is_delay = true; return apply_filters( 'sbi_is_api_delay', $is_delay ); } } } return apply_filters( 'sbi_is_api_delay', $is_delay ); } /** * Whether or not there is at least one critical error * * @return bool */ public function are_critical_errors() { if ( isset( $this->errors['connection']['critical'] ) ) { return true; } else { $connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts(); foreach ( $connected_accounts as $connected_account ) { if ( isset( $connected_account['private'] ) && sbi_private_account_near_expiration( $connected_account ) ) { return true; } $user_id = ! empty( $connected_account['user_id'] ) ? $connected_account['user_id'] : 0; $user_id = empty( $user_id ) && ! empty( $connected_account['account_id'] ) ? $connected_account['account_id'] : 0; if ( isset( $this->errors['accounts'][ $user_id ]['api'] ) ) { if ( isset( $this->errors['accounts'][ $user_id ]['api']['error'] ) ) { return $this->is_critical_error( $this->errors['accounts'][ $user_id ]['api'] ); } } } } return false; } /** * Whether or not there was a platform data clearing error * * @return bool */ public function was_app_permission_related_error() { return ! empty( $this->errors['revoked'] ); } public function get_app_permission_related_error_ids() { return $this->errors['revoked']; } /** * Delete any data associated with the Instagram API and the * connected account being deleted. * * @param $to_delete_connected_account */ public function delete_platform_data( $to_delete_connected_account ) { $are_other_business_accounts = false; $all_connected_accounts = SB_Instagram_Connected_Account::get_all_connected_accounts(); $to_update = array(); foreach ( $all_connected_accounts as $connected_account ) { if ( (int) $connected_account['user_id'] !== (int) $to_delete_connected_account['user_id'] ) { $to_update[ $connected_account['user_id'] ] = $connected_account; if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) { $are_other_business_accounts = true; } } } SB_Instagram_Connected_Account::update_connected_accounts( $to_update ); \InstagramFeed\Builder\SBI_Db::delete_source_by_account_id( $to_delete_connected_account['user_id'] ); $manager = new SB_Instagram_Data_Manager(); $manager->delete_caches(); $manager->delete_comments_data(); if ( empty( $to_update ) || ! $are_other_business_accounts ) { $manager->delete_hashtag_data(); } else { $manager->delete_non_hashtag_sbi_instagram_posts( $to_delete_connected_account['username'] ); } } } inc/class-sb-instagram-cache.php000064400000033575150515074560012606 0ustar00cache_time = (int) $cache_time; $this->is_legacy = strpos( $feed_id, '*' ) !== 0; $this->page = $page; if ( $this->page === 1 ) { $this->suffix = ''; } else { $this->suffix = '_' . $this->page; } $this->feed_id = str_replace( '*', '', $feed_id ); if ( is_admin() ) { $this->feed_id .= $this->maybe_customizer_suffix(); } $this->encryption = new SB_Instagram_Data_Encryption(); } /** * Set all caches based on available data. * * @since 6.0 */ public function retrieve_and_set() { $expired = true; $existing_caches = $this->query_sbi_feed_caches(); foreach ( $existing_caches as $cache ) { switch ( $cache['cache_key'] ) { case 'posts': $this->posts = $cache['cache_value']; if ( strtotime( $cache['last_updated'] ) > time() - $this->cache_time ) { $expired = false; } if ( empty( $cache['cache_value'] ) ) { $expired = true; } break; case 'posts' . $this->suffix: $this->posts_page = $cache['cache_value']; break; case 'header': $this->header = $cache['cache_value']; break; case 'resized_images' . $this->suffix: $this->resized_images = $cache['cache_value']; break; case 'meta' . $this->suffix: $this->meta = $cache['cache_value']; break; case 'posts_backup' . $this->suffix: $this->posts_backup = $cache['cache_value']; break; case 'header_backup' . $this->suffix: $this->header_backup = $cache['cache_value']; break; } } $this->is_expired = $expired; if ( $this->cache_time < 1 ) { $this->is_expired = true; } } /** * Whether or not the cache needs to be refreshed * * @param string $cache_type * * @return bool * * @since 6.0 */ public function is_expired( $cache_type = 'posts' ) { if ( $cache_type !== 'posts' ) { $cache = $this->get( $cache_type ); return ( empty( $cache ) || $this->is_expired ); } if ( $this->page === 1 ) { return $this->is_expired; } else { if ( $this->is_expired ) { return true; } if ( empty( $this->posts_page ) ) { return true; } } return false; } /** * Get data currently stored in the database for the type * * @param string $type * * @return string * * @since 6.0 */ public function get( $type ) { $return = array(); switch ( $type ) { case 'posts': $return = $this->posts; break; case 'posts' . $this->suffix: $return = $this->posts_page; break; case 'header': $return = $this->header; break; case 'resized_images': $return = $this->resized_images; break; case 'meta': $return = $this->meta; break; case 'posts_backup': $return = $this->posts_backup; break; case 'header_backup': $return = $this->header_backup; break; } return $this->maybe_decrypt( $return ); } /** * @param string $type * @param array $cache_value * * @since 6.0 */ public function set( $type, $cache_value ) { switch ( $type ) { case 'posts': $this->posts = $cache_value; break; case 'posts' . $this->suffix: $this->posts_page = $cache_value; break; case 'header': $this->header = $cache_value; break; case 'resized_images': $this->resized_images = $cache_value; break; case 'meta': $this->meta = $cache_value; break; case 'posts_backup': $this->posts_backup = $cache_value; break; case 'header_backup': $this->header_backup = $cache_value; break; } } /** * Update a single cache with new data. Try to accept any data and convert it * to JSON if needed * * @param string $cache_type * @param array|object|string $cache_value * @param bool $include_backup * @param bool $cron_update * * @return int * * @since 6.0 */ public function update_or_insert( $cache_type, $cache_value, $include_backup = true, $cron_update = true ) { $this->clear_wp_cache(); if ( $this->page > 1 || ( $cache_type !== 'posts' && $cache_type !== 'header' ) ) { $cron_update = false; } if ( strpos( $this->feed_id, '_CUSTOMIZER' ) !== false ) { $cron_update = false; } $cache_key = $cache_type . $this->suffix; $this->set( $cache_key, $cache_value ); if ( is_array( $cache_value ) || is_object( $cache_value ) ) { $cache_value = sbi_json_encode( $cache_value ); } global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $sql = $wpdb->prepare( " SELECT * FROM $cache_table_name WHERE feed_id = %s AND cache_key = %s", $this->feed_id, $cache_key ); $existing = $wpdb->get_results( $sql, ARRAY_A ); $data = array(); $where = array(); $format = array(); $data['cache_value'] = $this->maybe_encrypt( $cache_value ); $format[] = '%s'; $data['last_updated'] = date( 'Y-m-d H:i:s' ); $format[] = '%s'; if ( ! empty( $existing[0] ) ) { $where['feed_id'] = $this->feed_id; $where_format[] = '%s'; $where['cache_key'] = $cache_key; $where_format[] = '%s'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); } else { $data['cache_key'] = $cache_key; $format[] = '%s'; $data['cron_update'] = $cron_update === true ? 'yes' : ''; $format[] = '%s'; $data['feed_id'] = $this->feed_id; $format[] = '%s'; $affected = $wpdb->insert( $cache_table_name, $data, $format ); } return $affected; } /** * Tasks to do after a new set of posts are retrieved * * @since 6.0 */ public function after_new_posts_retrieved() { if ( $this->page === 1 ) { $this->clear( 'all' ); } } /** * Resets caches after they expire * * @param string $type * * @return bool|false|int * * @since 6.0 */ public function clear( $type ) { $this->clear_wp_cache(); global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $feed_id = str_replace( array( '_CUSTOMIZER', '_CUSTOMIZER_MODMODE' ), '', $this->feed_id ); if ( $type === 'all' ) { $affected = $wpdb->query( $wpdb->prepare( "UPDATE $cache_table_name SET cache_value = '' WHERE feed_id = %s AND cache_key NOT IN ( 'posts', 'posts_backup', 'header_backup' );", $feed_id ) ); $affected = $wpdb->query( $wpdb->prepare( "UPDATE $cache_table_name SET cache_value = '' WHERE feed_id = %s", $feed_id . '_CUSTOMIZER' ) ); $mod_mode_where = esc_sql( $feed_id ) . '_CUSTOMIZER_MODMODE%'; $affected = $wpdb->query( $wpdb->prepare( "UPDATE $cache_table_name SET cache_value = '' WHERE feed_id like %s", $mod_mode_where ) ); } else { $data = array( 'cache_value' => '' ); $format = array( '%s' ); $where['feed_id'] = $feed_id; $where_format[] = '%s'; $where['cache_key'] = $type . $this->suffix; $where_format[] = '%s'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); $where['feed_id'] = $feed_id . '_CUSTOMIZER'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); $where['feed_id'] = $feed_id . '_CUSTOMIZER_MODMODE'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); } return $affected; } public function get_customizer_cache() { if ( strpos( $this->feed_id, '_CUSTOMIZER' ) === false ) { $feed_id = $this->feed_id . '_CUSTOMIZER'; } else { $feed_id = $this->feed_id; } global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $sql = $wpdb->prepare( " SELECT * FROM $cache_table_name WHERE feed_id = %s AND cache_key = 'posts'", $feed_id ); $results = $wpdb->get_results( $sql, ARRAY_A ); $return = array(); if ( ! empty( $results[0] ) ) { $return = $this->maybe_decrypt( $results[0]['cache_value'] ); $return = json_decode( $return, true ); $return = isset( $return['data'] ) ? $return['data'] : array(); } return $return; } /** * Clears caches in the WP Options table used mostly by legacy feeds. * Also resets caches created by common page caching plugins * * @param false $hard_clear * @since 6.0 */ public static function clear_legacy( $hard_clear = false ) { global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; if ( $hard_clear ) { $affected = $wpdb->query( "DELETE FROM $cache_table_name WHERE feed_id LIKE ('sbi\_%') AND cache_key NOT IN ( 'posts_backup', 'header_backup' );" ); } else { $affected = $wpdb->query( "UPDATE $cache_table_name SET cache_value = '' WHERE feed_id LIKE ('sbi\_%') AND cache_key NOT IN ( 'posts_backup', 'header_backup' );" ); } sb_instagram_clear_page_caches(); } /** * Get all available caches from the sbi_cache table. * * @return array * * @since 6.0 */ private function query_sbi_feed_caches() { $feed_cache = wp_cache_get( $this->get_wp_cache_key() ); if ( false === $feed_cache ) { global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; if ( $this->page === 1 ) { $sql = $wpdb->prepare( " SELECT * FROM $cache_table_name WHERE feed_id = %s", $this->feed_id ); } else { $sql = $wpdb->prepare( " SELECT * FROM $cache_table_name WHERE feed_id = %s AND cache_key IN ( 'posts', %s, %s, %s )", $this->feed_id, 'posts_' . $this->page, 'resized_images_' . $this->page, 'meta_' . $this->page ); } $feed_cache = $wpdb->get_results( $sql, ARRAY_A ); wp_cache_set( $this->get_wp_cache_key(), $feed_cache ); } return $feed_cache; } /** * Delete the wp_cache * * @since 6.0 */ private function clear_wp_cache() { wp_cache_delete( $this->get_wp_cache_key() ); } /** * Key used to get the wp cache key * * @return string * * @since 6.0 */ private function get_wp_cache_key() { return 'sbi_feed_' . $this->feed_id . '_' . $this->page; } /** * Uses a raw value and attempts to encrypt it * * @param $value * * @return bool|string * * @since 6.0 */ private function maybe_encrypt( $value ) { if ( ! empty( $value ) && ! is_string( $value ) ) { $value = sbi_json_encode( $value ); } if ( empty( $value ) ) { return $value; } return $this->encryption->encrypt( $value ); } /** * Uses a raw value and attempts to decrypt it * * @param $value * * @return bool|string * * @since 6.0 */ private function maybe_decrypt( $value ) { if ( ! is_string( $value ) ) { return $value; } if ( strpos( $value, '{' ) === 0 ) { return $value; } $decrypted = $this->encryption->decrypt( $value ); if ( ! $decrypted ) { return $value; } return $decrypted; } /** * Add suffix to cache keys used in the customizer * * @return string * * @since 6.0 */ private function maybe_customizer_suffix() { $additional_suffix = ''; $in_customizer = ! empty( $_POST['previewSettings'] ) || ( isset( $_GET['page'] ) && $_GET['page'] === 'sbi-feed-builder' ); if ( $in_customizer ) { $additional_suffix .= '_CUSTOMIZER'; if ( ! empty( $_POST['moderationShoppableMode'] ) ) { $additional_suffix .= '_MODMODE'; $offset = ! empty( $_POST['moderationShoppableModeOffset'] ) ? intval( $_POST['moderationShoppableModeOffset'] ) : ''; $additional_suffix .= $offset; } } return $additional_suffix; } public function update_last_updated() { global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $data = array(); $format = array(); $where_format = array(); $data['last_updated'] = date( 'Y-m-d H:i:s' ); $format[] = '%s'; $where['feed_id'] = $this->feed_id; $where_format[] = '%s'; $where['cache_key'] = 'posts'; $where_format[] = '%s'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); $data = array(); $format = array(); $where_format = array(); $data['last_updated'] = date( 'Y-m-d H:i:s' ); $format[] = '%s'; $where['feed_id'] = $this->feed_id; $where_format[] = '%s'; $where['cache_key'] = 'header'; $where_format[] = '%s'; $affected = $wpdb->update( $cache_table_name, $data, $where, $format, $where_format ); return $affected; } /** * Get active/all cache count. * * @param bool $active when set to true only items updated in the last months are returned. * * @return int */ public function get_cache_count($active = false) { global $wpdb; $cache_table_name = $wpdb->prefix . 'sbi_feed_caches'; $query = "SELECT COUNT(DISTINCT feed_id, cache_key) as cache_count FROM $cache_table_name WHERE feed_id Not Like '%_CUSTOMIZER%'"; if($active === true) { $query .= " AND feed_id Not Like '%_MODMODE%' AND last_updated >= DATE_SUB(NOW(), INTERVAL 1 MONTH)"; } $sql = $wpdb->prepare($query); $caches = $wpdb->get_results( $sql ); if(!empty($caches)) { return $caches[0]->cache_count; } return 0; } } inc/class-sb-instagram-feed-locator.php000064400000043710150515074560014077 0ustar00 $transient_name, * 'atts' => $atts, * 'location' => array( * 'post_id' => get_the_ID(), * 'html' => 'unknown' * ) * ); */ $this->feed_details = $feed_details; $this->matching_entries = array(); $this->expiration_time = time() - 2 * WEEK_IN_SECONDS; } /** * Returns records that match the post ID and feed ID * of the feed being located * * @return array * * @since 5.11 */ public function retrieve_matching_entries() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $results = $wpdb->get_results( $wpdb->prepare( " SELECT * FROM $feed_locator_table_name WHERE post_id = %d AND feed_id = %s", $this->feed_details['location']['post_id'], $this->feed_details['feed_id'] ), ARRAY_A ); return $results; } /** * Add feed being located to the database * * @since 5.11 */ public function insert_entry() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $two_minutes_ago = date( 'Y-m-d H:i:s', time() - 120 ); $results_recent_entries = $wpdb->get_results( $wpdb->prepare(" SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name WHERE last_update > %s; ", $two_minutes_ago ), ARRAY_A ); // Only allow 5 new entries within 5 minutes if ( isset( $results_recent_entries[0]['num_entries'] ) && (int)$results_recent_entries[0]['num_entries'] > 5 ) { return; } // Only allow 1000 total entries $results_total_entries = $wpdb->get_results( " SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name", ARRAY_A ); if ( isset( $results_total_entries[0]['num_entries'] ) && (int)$results_total_entries[0]['num_entries'] > 1000 ) { $this->delete_oldest_entry(); } $affected = $wpdb->query( $wpdb->prepare( "INSERT INTO $feed_locator_table_name (feed_id, post_id, html_location, shortcode_atts, last_update) VALUES ( %s, %d, %s, %s, %s);", $this->feed_details['feed_id'], $this->feed_details['location']['post_id'], $this->feed_details['location']['html'], sbi_json_encode( $this->feed_details['atts'] ), date( 'Y-m-d H:i:s' ) ) ); } /** * Update a record based on the existing "id" column. Location can change * from "unknown" to one of footer, content, header, or sidebar. * * @param $id * @param $location * * @since 5.11 */ public function update_entry( $id, $location ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $query = $wpdb->query( $wpdb->prepare( " UPDATE $feed_locator_table_name SET last_update = %s, html_location = %s WHERE id = %d;", date( 'Y-m-d H:i:s' ), $location, $id ) ); } /** * Processes a feed being located based on whether or not the record * exists as well as whether or not an unknown location needs to be * updated. * * @since 5.11 */ public function add_or_update_entry() { if ( empty( $this->feed_details['feed_id'] ) ) { return; } if ( empty( $this->feed_details['location']['post_id'] ) ) { return; } $this->matching_entries = $this->retrieve_matching_entries(); if ( empty( $this->matching_entries ) ) { $this->insert_entry(); } else { $matching_indices = array(); $matched_location = false; $non_unknown_match = false; $unknown_match = false; foreach ( $this->matching_entries as $index => $matching_entry ) { $details_atts = is_array( $this->feed_details['atts'] ) ? $this->feed_details['atts'] : array(); $matching_atts = json_decode( $matching_entry['shortcode_atts'], true ); if ( ! is_array( $matching_atts ) ) { $matching_atts = array(); } $atts_diff = array_diff( $matching_atts, $details_atts ); // determines if the shortcode settings match the shortcode settings of an existing feed if ( empty( $atts_diff ) ) { $matching_indices[] = $matching_entry['id']; if ( $matching_entry['html_location'] === $this->feed_details['location']['html'] ) { $matched_location = $index; $this->update_entry( $matching_entry['id'], $matching_entry['html_location'] ); } if ( $matching_entry['html_location'] !== 'unknown' ) { $non_unknown_match = $index; } else { $unknown_match = $index; } } } if ( false === $matched_location ) { // if there is no matched location, there is only one feed on the page, and the feed being checked has an unknown location, update the known location if ( count( $matching_indices ) === 1 && $this->feed_details['location']['html'] === 'unknown' && false !== $non_unknown_match ) { $this->update_entry( $this->matching_entries[ $non_unknown_match ]['id'], $this->matching_entries[ $non_unknown_match ]['html_location'] ); } else { if ( $this->feed_details['location']['html'] !== 'unknown' && false !== $unknown_match ) { $this->update_entry( $this->matching_entries[ $unknown_match ]['id'], $this->feed_details['location']['html'] ); } else { $this->insert_entry(); } } } } } public function delete_oldest_entry() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $affected = $wpdb->query( "DELETE FROM $feed_locator_table_name ORDER BY last_update ASC LIMIT 1;" ); } /** * Queries the locator table for feeds by feed_id * * @param $args * * @return array|object|null * * @since 4.0 */ public static function instagram_feed_locator_query( $args ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $group_by = isset( $args['group_by'] ) ? self::sanitize_group_by( $args['group_by'] ) : ''; $location_string = 'content'; if ( isset( $args['html_location'] ) ) { $locations = array_map( 'esc_sql', $args['html_location'] ); $location_string = implode( "', '", $locations ); } $page = 0; if ( isset( $args['page'] ) ) { $page = (int) $args['page'] - 1; unset( $args['page'] ); } $offset = max( 0, $page * InstagramFeed\Builder\SBI_Db::RESULTS_PER_PAGE ); if ( isset( $args['shortcode_atts'] ) ) { $results = $wpdb->get_results( $wpdb->prepare( " SELECT * FROM $feed_locator_table_name WHERE shortcode_atts = %s AND html_location IN ( '$location_string' ) $group_by LIMIT %d OFFSET %d;", $args['shortcode_atts'], InstagramFeed\Builder\SBI_Db::RESULTS_PER_PAGE, $offset ), ARRAY_A ); } else { $results = $wpdb->get_results( $wpdb->prepare( " SELECT * FROM $feed_locator_table_name WHERE feed_id = %s AND html_location IN ( '$location_string' ) $group_by LIMIT %d OFFSET %d;", $args['feed_id'], InstagramFeed\Builder\SBI_Db::RESULTS_PER_PAGE, $offset ), ARRAY_A ); } return $results; } /** * Queries all legacy feeds that have been located * * @param $args * * @return array|object|null * * @since 4.0 */ public static function legacy_instagram_feed_locator_query( $args ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $group_by = isset( $args['group_by'] ) ? self::sanitize_group_by( $args['group_by'] ) : ''; $location_string = 'content'; if ( isset( $args['html_location'] ) ) { $locations = array_map( 'esc_sql', $args['html_location'] ); $location_string = implode( "', '", $locations ); } $page = 0; if ( isset( $args['page'] ) ) { $page = (int) $args['page'] - 1; unset( $args['page'] ); } $offset = max( 0, $page * InstagramFeed\Builder\SBI_Db::RESULTS_PER_PAGE ); $limit = InstagramFeed\Builder\SBI_Db::RESULTS_PER_PAGE; $results = $wpdb->get_results( " SELECT * FROM $feed_locator_table_name WHERE feed_id NOT LIKE '*%' AND html_location IN ( '$location_string' ) $group_by LIMIT $limit OFFSET $offset;", ARRAY_A ); return $results; } public static function update_legacy_to_builder( $args ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $data = array( 'feed_id' => '*' . $args['new_feed_id'], 'shortcode_atts' => '{"feed":"' . $args['new_feed_id'] . '"}', ); $affected = $wpdb->query( $wpdb->prepare( "UPDATE $feed_locator_table_name SET feed_id = %s, shortcode_atts = %s", $data['feed_id'], $data['shortcode_atts'] ) ); return $affected; } /** * Simple count of rows based on args * * @param array $args * * @return int * * @since 4.0 */ public static function count( $args ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; if ( isset( $args['shortcode_atts'] ) ) { $results = $wpdb->get_results( $wpdb->prepare( " SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name WHERE shortcode_atts = %s ", $args['shortcode_atts'] ), ARRAY_A ); } else { $results = $wpdb->get_results( $wpdb->prepare( " SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name WHERE feed_id = %s ", $args['feed_id'] ), ARRAY_A ); } if ( isset( $results[0]['num_entries'] ) ) { return (int) $results[0]['num_entries']; } return 0; } /** * Old feeds are only detected once a day to keep load on the server low. * * @return bool * * @since 5.11 */ public static function should_clear_old_locations() { $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $last_old_feed_check = isset( $sbi_statuses_option['feed_locator']['last_check'] ) ? $sbi_statuses_option['feed_locator']['last_check'] : 0; return $last_old_feed_check < time() - DAY_IN_SECONDS; } /** * Old feeds are removed if they haven't been updated in two weeks. * * @since 5.11 */ public static function delete_old_locations() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $two_weeks_ago = date( 'Y-m-d H:i:s', time() - 2 * WEEK_IN_SECONDS ); $affected = $wpdb->query( $wpdb->prepare( "DELETE FROM $feed_locator_table_name WHERE last_update < %s;", $two_weeks_ago ) ); $sbi_statuses_option = get_option( 'sbi_statuses', array() ); $sbi_statuses_option['feed_locator']['last_check'] = time(); if ( ! isset( $sbi_statuses_option['feed_locator']['initialized'] ) ) { $sbi_statuses_option['feed_locator']['initialized'] = time(); } update_option( 'sbi_statuses', $sbi_statuses_option, true ); } /** * Feeds are located with the page load randomly (5% or 1/30 loads) * to decrease load on the server. * * If the locating just started (within 5 minutes) it is run more often * to collect feed locations quickly. * * @return bool * * @since 5.11 */ public static function should_do_locating() { if ( is_admin() || isset( $_GET['page'] ) && strpos( $_GET['page'], 'sbi' ) !== false ) { return false; } $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( isset( $sbi_statuses_option['feed_locator']['initialized'] ) && $sbi_statuses_option['feed_locator']['initialized'] < ( time() - 300 ) ) { $should_do_locating = rand( 1, 10 ) === 10; } else { $should_do_locating = rand( 1, 30 ) === 30; } $should_do_locating = apply_filters( 'sbi_should_do_locating', $should_do_locating ); return $should_do_locating; } /** * Simliar to the should_do_locating method but will add an additional * database query to see if there is a feed with an unknown location that * matches the details of the feed in question. * * @param $feed_id * @param $post_id * * @return bool * * @since 5.11 */ public static function should_do_ajax_locating( $feed_id, $post_id ) { if ( is_admin() || isset( $_GET['page'] ) && strpos( $_GET['page'], 'sbi' ) !== false ) { return false; } $sbi_statuses_option = get_option( 'sbi_statuses', array() ); if ( isset( $sbi_statuses_option['feed_locator']['initialized'] ) && $sbi_statuses_option['feed_locator']['initialized'] < ( time() - 300 ) ) { $should_do_locating = rand( 1, 10 ) === 10; } else { $should_do_locating = rand( 1, 30 ) === 30; } if ( $should_do_locating ) { $should_do_locating = self::entries_need_locating( $feed_id, $post_id ); } $should_do_locating = apply_filters( 'sbi_should_do_ajax_locating', $should_do_locating ); return $should_do_locating; } /** * Feeds are located with the page load randomly (1/30 loads) * to decrease load on the server. * * If the locating just started (within 5 minutes) it is run more often * to collect feed locations quickly. * * @param $feed_id * @param $post_id * * @return bool * * @since 5.11 */ public static function entries_need_locating( $feed_id, $post_id ) { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $one_day_ago = date( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS ); $results = $wpdb->get_results( $wpdb->prepare( " SELECT id FROM $feed_locator_table_name WHERE html_location = 'unknown' AND last_update < %s AND feed_id = %s AND post_id = %d LIMIT 1;", $one_day_ago, $feed_id, $post_id ), ARRAY_A ); return isset( $results[0] ); } /** * A custom table stores locations * * @since 5.11 */ public static function create_table() { global $wpdb; global $sb_instagram_posts_manager; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) !== $feed_locator_table_name ) { $sql = 'CREATE TABLE ' . $feed_locator_table_name . " ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, feed_id VARCHAR(50) DEFAULT '' NOT NULL, post_id BIGINT(20) UNSIGNED NOT NULL, html_location VARCHAR(50) DEFAULT 'unknown' NOT NULL, shortcode_atts LONGTEXT NOT NULL, last_update DATETIME );"; $wpdb->query( $sql ); } $error = $wpdb->last_error; $query = $wpdb->last_query; $had_error = false; if ( $wpdb->get_var( "show tables like '$feed_locator_table_name'" ) !== $feed_locator_table_name ) { $had_error = true; $sb_instagram_posts_manager->add_error( 'database_create', '' . __( 'There was an error when trying to create the database tables used to locate feeds.', 'instagram-feed' ) . '
' . $error . '
' . $query . '' ); } if ( ! $had_error ) { $wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX feed_id (feed_id)" ); $wpdb->query( "ALTER TABLE $feed_locator_table_name ADD INDEX post_id (post_id)" ); $sb_instagram_posts_manager->remove_error( 'database_create' ); } } /** * Counts the number of unique feeds in the database. * * @return int * * @since 5.11 */ public static function count_unique() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $results_content = $wpdb->get_results( " SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name WHERE html_location = 'content' ", ARRAY_A ); $results_other = $wpdb->get_results( " SELECT COUNT(*) AS num_entries FROM $feed_locator_table_name WHERE html_location != 'content' AND html_location != 'unknown' GROUP BY feed_id ", ARRAY_A ); $total = 0; if ( isset( $results_content[0]['num_entries'] ) ) { $total += (int) $results_content[0]['num_entries']; } if ( isset( $results_other[0]['num_entries'] ) ) { $total += (int) $results_other[0]['num_entries']; } return $total; } /** * Creates a summary of the located feeds in an array * * @return array * * @since 5.11 */ public static function summary() { global $wpdb; $feed_locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR; $locations = array( array( 'label' => __( 'Content', 'instagram-feed' ), 'html_locations' => array( 'content', 'unknown' ), ), array( 'label' => __( 'Header', 'instagram-feed' ), 'html_locations' => array( 'header' ), 'group_by' => 'feed_id', ), array( 'label' => __( 'Sidebar', 'instagram-feed' ), 'html_locations' => array( 'sidebar' ), 'group_by' => 'feed_id', ), array( 'label' => __( 'Footer', 'instagram-feed' ), 'html_locations' => array( 'footer' ), 'group_by' => 'feed_id', ), ); $one_result_found = false; foreach ( $locations as $key => $location ) { $in = implode( "', '", $location['html_locations'] ); $group_by = isset( $location['group_by'] ) ? self::sanitize_group_by( $location['group_by'] ) : ''; $results = $wpdb->get_results( " SELECT * FROM $feed_locator_table_name WHERE html_location IN ('$in') $group_by ORDER BY last_update ASC", ARRAY_A ); if ( isset( $results[0] ) ) { $one_result_found = true; } $locations[ $key ]['results'] = $results; } if ( ! $one_result_found ) { return array(); } return $locations; } public static function sanitize_group_by( $group_by ) { if ( in_array( $group_by, self::COLUMN_NAMES, true ) ) { return 'GROUP BY ' . $group_by; } return ''; } } admin/SBI_Support.php000064400000072244150515074560010537 0ustar00init(); } /** * Determining if the user is viewing the our page, if so, party on. * * @since 6.0 */ public function init() { if ( ! is_admin() ) { return; } add_action( 'admin_menu', array( $this, 'register_menu' ) ); } /** * Register Menu. * * @since 6.0 */ public function register_menu() { $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); $support_page = add_submenu_page( 'sb-instagram-feed', __( 'Support', 'instagram-feed' ), __( 'Support', 'instagram-feed' ), $cap, self::SLUG, array( $this, 'support_page' ), 4 ); add_action( 'load-' . $support_page, array( $this, 'support_page_enqueue_assets' ) ); } /** * Enqueue Extension CSS & Script. * * Loads only for Extension page * * @since 6.0 */ public function support_page_enqueue_assets() { if ( ! get_current_screen() ) { return; } $screen = get_current_screen(); if ( strpos( $screen->id, 'sbi-support' ) === false) { return; } wp_enqueue_style( 'sbi-fira-code-font', 'https://fonts.googleapis.com/css2?family=Fira+Code&display=swap', false, SBIVER ); wp_enqueue_style( 'support-style', SBI_PLUGIN_URL . 'admin/assets/css/support.css', false, SBIVER ); wp_enqueue_script( 'sb-vue', SBI_PLUGIN_URL . 'js/vue.min.js', null, '2.6.12', true ); wp_enqueue_script( 'support-app', SBI_PLUGIN_URL . 'admin/assets/js/support.js', null, SBIVER, true ); $sbi_support = $this->page_data(); wp_localize_script( 'support-app', 'sbi_support', $sbi_support ); } /** * Page Data to use in front end * * @since 6.0 * * @return array */ public function page_data() { $exported_feeds = SBI_Db::feeds_query(); $feeds = array(); foreach ( $exported_feeds as $feed_id => $feed ) { $feeds[] = array( 'id' => $feed['id'], 'name' => $feed['feed_name'], ); } $return = array( 'admin_url' => admin_url(), 'ajax_handler' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'sbi-admin' ), 'links' => \InstagramFeed\Builder\SBI_Feed_Builder::get_links_with_utm(), 'supportPageUrl' => admin_url( 'admin.php?page=sbi-support' ), 'siteSearchUrl' => 'https://smashballoon.com/search/', 'system_info' => $this->get_system_info(), 'system_info_n' => str_replace( '
', "\n", $this->get_system_info() ), 'feeds' => $feeds, 'supportUrl' => $this->get_support_url(), 'svgIcons' => SBI_Feed_Builder::builder_svg_icons(), 'socialWallLinks' => \InstagramFeed\Builder\SBI_Feed_Builder::get_social_wall_links(), 'socialWallActivated' => is_plugin_active( 'social-wall/social-wall.php' ), 'genericText' => array( 'help' => __( 'Help', 'instagram-feed' ), 'title' => __( 'Support', 'instagram-feed' ), 'gettingStarted' => __( 'Getting Started', 'instagram-feed' ), 'someHelpful' => __( 'Some helpful resources to get you started', 'instagram-feed' ), 'docsN' => __( 'Docs & Troubleshooting', 'instagram-feed' ), 'runInto' => __( 'Run into an issue? Check out our help docs.', 'instagram-feed' ), 'additionalR' => __( 'Additional Resources', 'instagram-feed' ), 'toHelp' => __( 'To help you get the most out of the plugin', 'instagram-feed' ), 'needMore' => __( 'Need more support? We’re here to help.', 'instagram-feed' ), 'ourFast' => __( 'Our fast and friendly support team is always happy to help!', 'instagram-feed' ), 'systemInfo' => __( 'System Info', 'instagram-feed' ), 'exportSettings' => __( 'Export Settings', 'instagram-feed' ), 'shareYour' => __( 'Share your plugin settings easily with Support', 'instagram-feed' ), 'copiedToClipboard' => __( 'Copied to clipboard', 'instagram-feed' ), ), 'buttons' => array( 'searchDoc' => __( 'Search Documentation', 'instagram-feed' ), 'moreHelp' => __( 'More help on Getting started', 'instagram-feed' ), 'viewDoc' => __( 'View Documentation', 'instagram-feed' ), 'viewBlog' => __( 'View Blog', 'instagram-feed' ), 'submitTicket' => __( 'Submit a Support Ticket', 'instagram-feed' ), 'copied' => __( 'Copied', 'instagram-feed' ), 'copy' => __( 'Copy', 'instagram-feed' ), 'export' => __( 'Export', 'instagram-feed' ), 'expand' => __( 'Expand', 'instagram-feed' ), 'collapse' => __( 'Collapse', 'instagram-feed' ), ), 'icons' => array( 'rocket' => SBI_PLUGIN_URL . 'admin/assets/img/rocket-icon.svg', 'book' => SBI_PLUGIN_URL . 'admin/assets/img/book-icon.svg', 'save' => SBI_PLUGIN_URL . 'admin/assets/img/save-plus-icon.svg', 'magnify' => '', 'rightAngle' => '', 'linkIcon' => '', 'plusIcon' => '', 'loaderSVG' => '', 'checkmarkSVG' => '', 'forum' => '', 'copy' => '', 'downAngle' => '', 'exportSVG' => '', ), 'images' => array( 'supportMembers' => SBI_PLUGIN_URL . 'admin/assets/img/support-members.png', ), 'articles' => array( 'gettingStarted' => array( array( 'title' => __( 'Creating your first Instagram feed', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/setting-up-the-instagram-feed-pro-wordpress-plugin/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Creating your first Instagram feed', ), array( 'title' => __( 'Instagram Business Profiles (required for Hashtag and Tagged feeds)', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/instagram-business-profiles/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Instagram Business Profiles', ), array( 'title' => __( 'Multiple User Accounts in One Feed', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/displaying-photos-multiple-ids-hashtags-feed/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Multiple Users', ), ), 'docs' => array( array( 'title' => __( 'Displaying Instagram Hashtag Feeds', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/displaying-an-instagram-hashtag-feed-on-your-website/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Displaying an Instagram Hashtag Feed', ), array( 'title' => __( 'How to Resolve Error Messages', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/instagram-api-error-message-reference/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Instagram resolving error messages', ), array( 'title' => __( 'My Feed Stopped Working or is Empty', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/my-photos-wont-load/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=My feed stopped working', ), ), 'resources' => array( array( 'title' => __( 'Differences Between an Instagram Personal and Business Account', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/differences-between-an-instagram-personal-and-business-account/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Differences between a business and personal account', ), array( 'title' => __( 'Display Posts With a Specific Hashtag From a Specific User Account', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/can-display-photos-specific-hashtag-specific-user-id/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Display a specific hashtag from a specific account', ), array( 'title' => __( 'Reauthorizing our Instagram/Facebook App', 'instagram-feed' ), 'link' => 'https://smashballoon.com/doc/reauthorizing-our-instagram-facebook-app/?utm_campaign=instagram-free&utm_source=support&utm_medium=docs&utm_content=Reauthorizing the Instagram or FB app', ), ), ), ); return $return; } /** * Get System Info * * @since 6.0 */ public function get_system_info() { $output = ''; // Build the output strings $output .= self::get_site_n_server_info(); $output .= self::get_active_plugins_info(); $output .= self::get_global_settings_info(); $output .= self::get_feeds_settings_info(); $output .= self::get_sources_info(); $output .= self::get_image_resizing_info(); $output .= self::get_posts_table_info(); $output .= self::get_cron_report(); $output .= self::get_errors_info(); $output .= self::get_action_logs_info(); $output .= self::get_oembeds_info(); return $output; } /** * Get Site and Server Info * * @since 6.0 * * @return string */ public static function get_site_n_server_info() { $allow_url_fopen = ini_get( 'allow_url_fopen' ) ? 'Yes' : 'No'; $php_curl = is_callable( 'curl_init' ) ? 'Yes' : 'No'; $php_json_decode = function_exists( 'json_decode' ) ? 'Yes' : 'No'; $php_ssl = in_array( 'https', stream_get_wrappers(), true ) ? 'Yes' : 'No'; $output = '## SITE/SERVER INFO: ##
'; $output .= 'Plugin Version:' . self::get_whitespace( 11 ) . esc_html( SBI_PLUGIN_NAME ) . '
'; $output .= 'Site URL:' . self::get_whitespace( 17 ) . esc_html( site_url() ) . '
'; $output .= 'Home URL:' . self::get_whitespace( 17 ) . esc_html( home_url() ) . '
'; $output .= 'WordPress Version:' . self::get_whitespace( 8 ) . esc_html( get_bloginfo( 'version' ) ) . '
'; $output .= 'PHP Version:' . self::get_whitespace( 14 ) . esc_html( PHP_VERSION ) . '
'; $output .= 'Web Server Info:' . self::get_whitespace( 10 ) . esc_html( $_SERVER['SERVER_SOFTWARE'] ) . '
'; $output .= 'PHP allow_url_fopen:' . self::get_whitespace( 6 ) . esc_html( $allow_url_fopen ) . '
'; $output .= 'PHP cURL:' . self::get_whitespace( 17 ) . esc_html( $php_curl ) . '
'; $output .= 'JSON:' . self::get_whitespace( 21 ) . esc_html( $php_json_decode ) . '
'; $output .= 'SSL Stream:' . self::get_whitespace( 15 ) . esc_html( $php_ssl ) . '
'; $output .= '
'; return $output; } /** * Get Active Plugins * * @since 6.0 * * @return string */ public static function get_active_plugins_info() { $plugins = get_plugins(); $active_plugins = get_option( 'active_plugins' ); $output = '## ACTIVE PLUGINS: ##
'; foreach ( $plugins as $plugin_path => $plugin ) { if ( in_array( $plugin_path, $active_plugins, true ) ) { $output .= esc_html( $plugin['Name'] ) . ': ' . esc_html( $plugin['Version'] ) . '
'; } } $output .= '
'; return $output; } /** * Get Global Settings * * @since 6.0 * * @return string */ public static function get_global_settings_info() { $output = '## GLOBAL SETTINGS: ##
'; $sbi_license_key = get_option( 'sbi_license_key' ); $sbi_license_data = get_option( 'sbi_license_data' ); $sbi_license_status = get_option( 'sbi_license_status' ); $sbi_settings = get_option( 'sb_instagram_settings', array() ); $usage_tracking = get_option( 'sbi_usage_tracking', array( 'last_send' => 0, 'enabled' => \sbi_is_pro_version(), ) ); $output .= 'License key: '; if ( $sbi_license_key ) { $output .= esc_html( $sbi_license_key ); } else { $output .= ' Not added'; } $output .= '
'; $output .= 'License status: '; if ( $sbi_license_status ) { $output .= $sbi_license_status; } else { $output .= ' Inactive'; } $output .= '
'; $output .= 'Preserve settings if plugin is removed: '; $output .= ( $sbi_settings['sb_instagram_preserve_settings'] ) ? 'Yes' : 'No'; $output .= '
'; $output .= 'Connected Accounts: '; $output .= 'Placeholder!'; $output .= '
'; $output .= 'Caching: '; if ( wp_next_scheduled( 'sbi_feed_update' ) ) { $time_format = get_option( 'time_format' ); if ( ! $time_format ) { $time_format = 'g:i a'; } // $schedule = wp_get_schedule( 'sbi_feed_update' ); if ( $schedule === '30mins' ) { $schedule = __( 'every 30 minutes', 'instagram-feed' ); } if ( $schedule === 'twicedaily' ) { $schedule = __( 'every 12 hours', 'instagram-feed' ); } $sbi_next_cron_event = wp_next_scheduled( 'sbi_feed_update' ); $output = __( 'Next check', 'instagram-feed' ) . ': ' . gmdate( $time_format, $sbi_next_cron_event + sbi_get_utc_offset() ) . ' (' . $schedule . ')'; } else { $output .= 'Nothing currently scheduled'; } $output .= '
'; $output .= 'GDPR: '; $output .= isset( $sbi_settings['gdpr'] ) ? $sbi_settings['gdpr'] : ' Not setup'; $output .= '
'; $output .= 'Custom CSS: '; $output .= isset( $sbi_settings['sb_instagram_custom_css'] ) && ! empty( $sbi_settings['sb_instagram_custom_css'] ) ? wp_strip_all_tags( $sbi_settings['sb_instagram_custom_css'] ) : 'Empty'; $output .= '
'; $output .= 'Custom JS: '; $output .= isset( $sbi_settings['sb_instagram_custom_js'] ) && ! empty( $sbi_settings['sb_instagram_custom_js'] ) ? $sbi_settings['sb_instagram_custom_js'] : 'Empty'; $output .= '
'; $output .= 'Optimize Images: '; $output .= isset( $sbi_settings['sb_instagram_disable_resize'] ) && ! $sbi_settings['sb_instagram_disable_resize'] ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Usage Tracking: '; $output .= isset( $usage_tracking['enabled'] ) && $usage_tracking['enabled'] === true ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'AJAX theme loading fix: '; $output .= isset( $sbi_settings['sb_instagram_ajax_theme'] ) && $sbi_settings['sb_instagram_ajax_theme'] ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'AJAX Initial: '; $output .= isset( $sbi_settings['sb_ajax_initial'] ) && $sbi_settings['sb_ajax_initial'] === true ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Enqueue in Head: '; $output .= isset( $sbi_settings['enqueue_js_in_head'] ) && $sbi_settings['enqueue_js_in_head'] === true ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Enqueue in Shortcode: '; $output .= isset( $sbi_settings['enqueue_css_in_shortcode'] ) && $sbi_settings['enqueue_css_in_shortcode'] === true ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Enable JS Image: '; $output .= isset( $sbi_settings['disable_js_image_loading'] ) && $sbi_settings['disable_js_image_loading'] === false ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Admin Error Notice: '; $output .= isset( $sbi_settings['disable_admin_notice'] ) && $sbi_settings['disable_admin_notice'] === false ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Feed Issue Email Reports: '; $output .= isset( $sbi_settings['enable_email_report'] ) && $sbi_settings['enable_email_report'] === true ? 'Enabled' : 'Disabled'; $output .= '
'; $output .= 'Email notification: '; $output .= isset( $sbi_settings['email_notification'] ) && $sbi_settings['email_notification'] !== null ? ucfirst( $sbi_settings['email_notification'] ) : 'Off'; $output .= '
'; $output .= 'Email notification addresses: '; $output .= isset( $sbi_settings['email_notification_addresses'] ) && ! empty( $sbi_settings['email_notification_addresses'] ) ? sanitize_email( $sbi_settings['email_notification_addresses'] ) : 'Not available'; $output .= '
'; $output .= '
'; return $output; } /** * Get Feeds Settings * * @since 6.0 * * @return string */ public static function get_feeds_settings_info() { $output = '## FEEDS: ##
'; $feeds_list = SBI_Feed_Builder::get_feed_list(); $source_list = SBI_Feed_Builder::get_source_list(); $manager = new \SB_Instagram_Data_Manager(); $i = 0; foreach ( $feeds_list as $feed ) { $type = ! empty( $feed['settings']['type'] ) ? $feed['settings']['type'] : 'user'; if ( $i >= 25 ) { break; } $output .= $feed['feed_name']; if ( isset( $feed['settings'] ) ) { $output .= ' - ' . ucfirst( $type ); $output .= '
'; if ( ! empty( $feed['settings']['sources'] ) ) { foreach ( $feed['settings']['sources'] as $id => $source ) { $output .= esc_html( $source['username'] ); $output .= ' (' . esc_html( $id ) . ')'; $output .= '
'; $output .= esc_html( $manager->remote_encrypt( $source['access_token'] ) ); } } } $output .= '
'; if ( isset( $feed['location_summary'] ) && count( $feed['location_summary'] ) > 0 ) { $first_feed = $feed['location_summary'][0]; if ( ! empty( $first_feed['link'] ) ) { $output .= esc_html( $first_feed['link'] ) . '?sb_debug'; $output .= '
'; } } if ( $i < ( count( $feeds_list ) - 1 ) ) { $output .= '
'; } $i++; } $output .= '
'; return $output; } /** * Get Feeds Settings * * @since 6.0 * * @return string */ public static function get_sources_info() { $output = '## Sources: ##
'; $source_list = SBI_Feed_Builder::get_source_list(); $manager = new \SB_Instagram_Data_Manager(); foreach ( $source_list as $source ) { $output .= $source['account_id']; $output .= '
'; $output .= 'Type: ' . esc_html( $source['account_type'] ); $output .= '
'; $output .= 'Username: ' . esc_html( $source['username'] ); $output .= '
'; $output .= 'Error: ' . esc_html( $source['error'] ); $output .= '
'; $output .= esc_html( $manager->remote_encrypt( $source['access_token'] ) ); $output .= '
'; $output .= '
'; } $output .= '
'; return $output; } /** * Get Reports * * @since 6.0 * * @return string */ public static function get_cron_report() { $output = '## Cron Cache Report: ##
'; $cron_report = get_option( 'sbi_cron_report', array() ); if ( ! empty( $cron_report ) ) { $output .= 'Time Ran: ' . esc_html( $cron_report['notes']['time_ran'] ); $output .= "
"; $output .= 'Found Feeds: ' . esc_html( $cron_report['notes']['num_found_transients'] ); $output .= "
"; $output .= "
"; foreach ( $cron_report as $key => $value ) { if ( $key !== 'notes' ) { $output .= esc_html( $key ) . ':'; $output .= "
"; if ( ! empty( $value['last_retrieve'] ) ) { $output .= 'Last Retrieve: ' . esc_html( $value['last_retrieve'] ); $output .= "
"; } $output .= 'Did Update: ' . esc_html( $value['did_update'] ); $output .= "
"; $output .= "
"; } } } else { $output .= "
"; } $cron = _get_cron_array(); foreach ( $cron as $key => $data ) { $is_target = false; foreach ( $data as $key2 => $val ) { if ( strpos( $key2, 'sbi' ) !== false || strpos( $key2, 'sb_instagram' ) !== false ) { $is_target = true; $output .= esc_html( $key2 ); $output .= "
"; } } if ( $is_target ) { $output .= esc_html( date( 'Y-m-d H:i:s', $key ) ); $output .= "
"; $output .= esc_html( 'Next Scheduled: ' . round( ( (int) $key - time() ) / 60 ) . ' minutes' ); $output .= "
"; $output .= "
"; } } return $output; } /** * Get Image Resizing Info * * @since 6.0 * * @return string */ public static function get_image_resizing_info() { $output = '## IMAGE RESIZING: ##
'; $upload = wp_upload_dir(); $upload_dir = $upload['basedir']; $upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME; if ( file_exists( $upload_dir ) ) { $output .= 'upload directory exists
'; } else { $created = wp_mkdir_p( $upload_dir ); if ( ! $created ) { $output .= 'cannot create upload directory'; } } $output .= '
'; return $output; } /** * Get Posts Table Info * * @since 6.0 * * @return string */ public static function get_posts_table_info() { $output = '## POSTS: ##
'; global $wpdb; $table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE; $feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS; if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) !== $feeds_posts_table_name ) { $output .= 'no feeds posts table
'; } else { $last_result = $wpdb->get_results( "SELECT * FROM $feeds_posts_table_name ORDER BY id DESC LIMIT 1;" ); if ( is_array( $last_result ) && isset( $last_result[0] ) ) { $output .= '## FEEDS POSTS TABLE ##
'; foreach ( $last_result as $column ) { foreach ( $column as $key => $value ) { $output .= esc_html( $key ) . ': ' . esc_html( $value ) . '
'; } } } else { $output .= 'feeds posts has no rows'; $output .= '
'; } } $output .= '
'; if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) { $output .= 'no posts table
'; } else { $last_result = $wpdb->get_results( "SELECT * FROM $table_name ORDER BY id DESC LIMIT 1;" ); if ( is_array( $last_result ) && isset( $last_result[0] ) ) { $output .= '## POSTS TABLE ##'; $output .= '
'; foreach ( $last_result as $column ) { foreach ( $column as $key => $value ) { $output .= esc_html( $key ) . ': ' . esc_html( $value ) . '
'; } } } else { $output .= 'posts has no rows
'; } } $output .= '
'; return $output; } /** * SBI Get Errors Info * * @since 6.0 * * @return string */ public static function get_errors_info() { $output = '## ERRORS: ##
'; global $sb_instagram_posts_manager; $errors = $sb_instagram_posts_manager->get_errors(); if ( ! empty( $errors['resizing'] ) ) : $output .= '* Resizing *
'; $output .= esc_html( $errors['resizing'] ) . '
'; endif; if ( ! empty( $errors['database_create'] ) ) : $output .= '* Database Create *
'; $output .= esc_html( $errors['database_create'] ) . '
'; endif; if ( ! empty( $errors['upload_dir'] ) ) : $output .= '* Uploads Directory *
'; $output .= esc_html( $errors['upload_dir'] ) . '
'; endif; if ( ! empty( $errors['connection'] ) ) : $output .= '* API/WP_HTTP Request *
'; if ( is_array( $errors['connection'] ) ) { foreach ( $errors['connection'] as $con_error ) { if ( is_array( $con_error ) ) { foreach ( $con_error as $subcon_error ) { $output .= esc_html( $subcon_error ) . '
'; } } else { $output .= esc_html( $con_error ) . '
'; } } } else { $output .= esc_html( $errors['connection'] ); } endif; $output .= '
'; return $output; } /** * Get Action Logs Info * * @since 6.0 * * @return string */ public static function get_action_logs_info() { $output = '## ACTION LOG ##
'; global $sb_instagram_posts_manager; $actions = $sb_instagram_posts_manager->get_action_log(); if ( ! empty( $actions ) ) : foreach ( $actions as $action ) : $output .= strip_tags( $action ) . '
'; endforeach; endif; $output .= '
'; return $output; } /** * Get Feeds Settings * * @since 6.0 * * @return string */ public static function get_oembeds_info() { $output = '## OEMBED: ##
'; $oembed_token_settings = get_option( 'sbi_oembed_token', array() ); foreach ( $oembed_token_settings as $key => $value ) { if ( $key === 'access_token' ) { $manager = new \SB_Instagram_Data_Manager(); $output .= esc_html( $key ) . ': ' . esc_html( $manager->remote_encrypt( $value ) ) . '
'; } else { $output .= esc_html( $key ) . ': ' . esc_html( $value ) . '
'; } } return $output; } /** * SBI Get Support URL * * @since 6.0 * * @return string $url */ public function get_support_url() { $url = 'https://smashballoon.com/instagram-feed/support/'; $license_type = sbi_is_pro_version() ? 'pro' : 'free'; $args = array(); $license_key = get_option( 'sbi_license_key' ); if ( $license_key ) { $license_key = sbi_encrypt_decrypt( 'encrypt', $license_key ); $args['license'] = $license_key; } $args['license_type'] = $license_type; $args['version'] = SBIVER; $url = add_query_arg( $args, $url ); return $url; } /** * SBI Get Whitespace * * @since 6.0 * * @param int $times * * @return string */ public static function get_whitespace( $times ) { return str_repeat( ' ', $times ); } /** * Extensions Manager Page View Template * * @since 6.0 */ public function support_page() { SBI_View::render( 'support.index' ); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������admin/SBI_HTTP_Request.php��������������������������������������������������������������������������0000644�����������������00000003707�15051507456�0011350 0����������������������������������������������������������������������������������������������������ustar�00������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� array( 'Content-Type' => 'application/json', ), ); $args = array_merge( $args, $data ); if ( 'GET' === $method ) { $request = wp_remote_get( $url, $args ); } elseif ( 'DELETE' === $method ) { $args['method'] = 'DELETE'; $request = wp_remote_request( $url, $args ); } elseif ( 'PATCH' === $method ) { $args['method'] = 'PATCH'; $request = wp_remote_request( $url, $args ); } elseif ( 'PUT' === $method ) { $args['method'] = 'PUT'; $request = wp_remote_request( $url, $args ); } else { $args['method'] = 'POST'; $request = wp_remote_post( $url, $args ); } return $request; } /** * Check if WP_Error returned * * @param array|WP_Error $request * * @since 4.0 * * @return array|WP_Error */ public static function is_error( $request ) { return is_wp_error( $request ); } /** * Get the remote call status code * * @param array|WP_Error $request * * @since 4.0 * * @return array|WP_Error */ public static function status( $request ) { if ( is_wp_error( $request ) ) { return; } return wp_remote_retrieve_response_code( $request ); } /** * Get the remote call body data * * @param array|WP_Error $request * * @since 4.0 * * @return array $response */ public static function data( $request ) { $response = wp_remote_retrieve_body( $request ); return json_decode( $response ); } } ���������������������������������������������������������admin/SBI_Admin_Notices.php�������������������������������������������������������������������������0000644�����������������00000044342�15051507456�0011575 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������init(); } /** * Determining if the user is viewing the our page, if so, party on. * * @since 4.0 */ public function init() { if ( ! is_admin() ) { return; } add_action( 'in_admin_header', [ $this, 'remove_admin_notices' ] ); add_action( 'wp_ajax_sbi_check_license', [ $this, 'sbi_check_license' ] ); add_action( 'sbi_header_notices', array( $this, 'header_notices' ) ); add_action( 'wp_ajax_sbi_dismiss_upgrade_notice', array( $this, 'dismiss_upgrade_notice' ) ); } /** * Header Notices * * @since 6.0 */ public function header_notices() { $lite_notice_dismissed = get_transient( 'instagram_feed_dismiss_lite' ); if ( $lite_notice_dismissed ) { return; } $output = ''; $upgrade_url = 'https://smashballoon.com/instagram-feed/demo/?utm_campaign=instagram-free&utm_source=lite-upgrade-bar'; $output .= '
'; $output .= sprintf( '%s %s', __('You\'re using Instagram Feed Lite. To unlock more features consider', 'instagram-feed'), $upgrade_url, __('upgrading to Pro', 'instagram-feed') ); $output .= sprintf( '', __('Dismiss this message', 'instagram-feed'), '' ); $output .= '
'; echo $output; } /** * Dismiss Upgrade Notice * * @since 6.0 * * @return SBI_Response */ public function dismiss_upgrade_notice() { // Run a security check. check_ajax_referer( 'sbi_nonce' , 'sbi_nonce'); $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); if ( ! current_user_can( $cap ) ) { wp_send_json_error(); // This auto-dies. } // set the transient so it will hide for next 7 days set_transient( 'instagram_feed_dismiss_lite', 'dismiss', 1 * WEEK_IN_SECONDS ); new SBI_Response( true, array() ); } /** * Remove admin notices from inside our plugin screens so we can show our customized notices * * @since 4.0 */ public function remove_admin_notices() { $current_screen = get_current_screen(); $not_allowed_screens = array( 'instagram-feed_page_sbi-feed-builder', 'instagram-feed_page_sbi-settings', 'instagram-feed_page_sbi-oembeds-manager', 'instagram-feed_page_sbi-extensions-manager', 'instagram-feed_page_sbi-about-us', 'instagram-feed_page_sbi-support', ); if ( in_array( $current_screen->base, $not_allowed_screens ) || strpos( $current_screen->base, 'sbi-' ) !== false ) { remove_all_actions('admin_notices'); remove_all_actions('all_admin_notices'); } } /** * CFF Get Renew License URL * * @since 4.0 * * @return string $url */ public function get_renew_url() { global $sbi_download_id; $license_key = get_option( 'sbi_license_key' ) ? get_option( 'sbi_license_key' ) : null; $url = sprintf( 'https://smashballoon.com/checkout/?edd_license_key=%s&download_id=%s&utm_campaign=instagram-free&utm_source=expired-notice&utm_medium=renew-license', $license_key, $sbi_download_id ); return $url; } /** * CFF Check License * * @since 4.0 * * @return SBI_Response */ public function sbi_check_license() { // Run a security check. check_ajax_referer( 'sbi_nonce' , 'sbi_nonce'); $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); if ( ! current_user_can( $cap ) ) { wp_send_json_error(); // This auto-dies. } $sbi_license = trim( get_option( 'sbi_license_key' ) ); // Check the API $sbi_api_params = array( 'edd_action'=> 'check_license', 'nocache' => '1', 'license' => $sbi_license, 'item_name' => urlencode( SBI_PLUGIN_NAME ) // the name of our product in EDD ); $sbi_response = wp_remote_get( add_query_arg( $sbi_api_params, SBI_STORE_URL ), array( 'timeout' => 60 ) ); $sbi_license_data = (array) json_decode( wp_remote_retrieve_body( $sbi_response ) ); // Update the updated license data update_option( 'sbi_license_data', $sbi_license_data ); $sbi_todays_date = date('Y-m-d'); // Check whether it's active if( $sbi_license_data['license'] !== 'expired' && ( strtotime( $sbi_license_data['expires'] ) > strtotime($sbi_todays_date) ) ) { // if the license is active then lets remove the ignore check for dashboard so next time it will show the expired notice in dashboard screen update_user_meta( get_current_user_id(), 'sbi_ignore_dashboard_license_notice', false ); new SBI_Response( true, array( 'msg' => 'License Active', 'content' => $this->get_renewed_license_notice_content() ) ); } else { $content = 'Your Instagram Feed Pro license key has expired'; new SBI_Response( false, array( 'msg' => 'License Not Renewed', 'content' => $content ) ); } } /** * Get content for successfully renewed license notice * * @since 4.0 * * @return string $output */ public function get_renewed_license_notice_content() { $output = '

Thanks! Your license key is valid.

You can safely dismiss this modal.

Dismiss
'; return $output; } /** * Get modal content that will trigger by "Why Renew" button * * @since 4.0 * * @return string $output */ public function get_modal_content() { $output = '

Why Renew?

See below for why it\'s so important to keep an active plugin license.

Protected Against All Upcoming Instagram Platform Updates and API Changes

Don\'t worry about your Instagram feeds breaking due to constant changes in the Instagram platform. Stay protected with access to continual plugin updates, giving you peace of mind that the software will always be up to date.

Expert Technical Support

Without a valid license key you will no longer be able to receive updates or support for the Instagram Feed plugin. A renewed license key grants you access to our top-notch, quick and effective support for another full year.

WordPress Compatibility Updates

With WordPress updates being released continually, we make sure the plugin is always compatible with the latest version so you can update WordPress without needing to worry.

All Pro Instagram Feed Features

Photos & Albums, Videos (HD, 360, Live), Instagram Events, Popup Lightbox, Likes, Shares, & Reactions, Comments and Replies, Filter Posts, Post Layouts, Load More Posts, Multi-column Grid Layout, Background Caching, and more!

'; return $output; } } admin/SBI_Upgrader.php000064400000026566150515074560010642 0ustar00 'get_version', 'license' => $license_data['key'], 'item_name' => isset( $license_data['item_name'] ) ? $license_data['item_name'] : false, 'item_id' => isset( $license_data['item_id'] ) ? $license_data['item_id'] : false, 'version' => '0', 'slug' => self::SLUG, 'author' => 'SmashBalloon', 'url' => home_url(), 'beta' => false, 'nocache' => '1', ); $api_url = trailingslashit( self::STORE_URL ); $request = wp_remote_post( $api_url, array( 'timeout' => 15, 'sslverify' => true, 'body' => $api_params ) ); if ( ! is_wp_error( $request ) ) { $version_info = json_decode( wp_remote_retrieve_body( $request ) ); return $version_info; } return false; } /** * Ajax handler for grabbing the upgrade url. * * @since 4.0 */ public static function maybe_upgrade_redirect() { $home_url = home_url(); check_ajax_referer( 'sbi-admin' , 'nonce'); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); } // Check for permissions. if ( ! current_user_can( 'install_plugins' ) ) { wp_send_json_error( array( 'message' => esc_html__( 'You are not allowed to install plugins.', 'instagram-feed' ) ) ); } if ( SBI_Upgrader::is_dev_url( home_url() ) ) { wp_send_json_success( array( 'url' => self::INSTALL_INSTRUCTIONS, ) ); } // Check license key. $license = ! empty( $_POST['license_key'] ) ? sanitize_key( $_POST['license_key'] ) : ''; if ( empty( $license ) ) { wp_send_json_error( array( 'message' => esc_html__( 'You are not licensed.', 'instagram-feed' ) ) ); } $args = array( 'plugin_name' => self::NAME, 'plugin_slug' => 'pro', 'plugin_path' => plugin_basename( __FILE__ ), 'plugin_url' => trailingslashit( WP_PLUGIN_URL ) . 'pro', 'home_url' => $home_url, 'version' => '1.0', 'key' => $license, ); $url = add_query_arg( $args, self::CHECK_URL ); $remote_request_args = array( 'timeout' => '20', ); $response = wp_remote_get( $url, $remote_request_args ); if ( ! is_wp_error( $response ) ) { $body = wp_remote_retrieve_body( $response ); $check_key_response = json_decode( $body, true ); if ( empty( $check_key_response['license_data'] ) ) { wp_send_json_error( array( 'message' => esc_html( SBI_Upgrader::get_error_message( $check_key_response ) ), ) ); } if ( ! empty( $check_key_response['license_data']['error'] ) ) { wp_send_json_error( array( 'message' => SBI_Upgrader::get_error_message( $check_key_response ), ) ); } if ( ! empty( $check_key_response['license_data']['error'] ) ) { wp_send_json_error( array( 'message' => SBI_Upgrader::get_error_message( $check_key_response ), ) ); } if ( $check_key_response['license_data']['license'] !== 'valid' ) { wp_send_json_error( array( 'message' => SBI_Upgrader::get_error_message( $check_key_response ), ) ); } $license_data = $check_key_response['license_data']; update_option( 'sbi_license_key', $license ); update_option( 'sbi_license_data', $license_data ); update_option( 'sbi_license_status', $license_data['license'] ); // Redirect. $oth = hash( 'sha512', wp_rand() ); $hashed_oth = hash_hmac( 'sha512', $oth, wp_salt() ); update_option( 'sbi_one_click_upgrade', $oth ); $version = '1.0'; $version_info = SBI_Upgrader::get_version_info( $license_data ); $file = ''; if ( isset( $version_info->package ) ) { $file = $version_info->package; } $siteurl = admin_url(); $endpoint = admin_url( 'admin-ajax.php' ); $redirect = admin_url( 'admin.php?page=' . self::REDIRECT ); $url = add_query_arg( array( 'key' => $license, 'oth' => $hashed_oth, 'endpoint' => $endpoint, 'version' => $version, 'siteurl' => $siteurl, 'homeurl' => $home_url, 'redirect' => rawurldecode( base64_encode( $redirect ) ), 'file' => rawurldecode( base64_encode( $file ) ), 'plugin_name' => self::NAME, ), self::UPGRADE_URL ); wp_send_json_success( array( 'url' => $url, ) ); } wp_send_json_error( array( 'message' => esc_html__( 'Could not connect.', 'instagram-feed' ) ) ); } /** * Endpoint for one-click upgrade. * * @since 4.0 */ function install_upgrade() { $error = esc_html__( 'Could not install upgrade. Please download from smashballoon.com and install manually.', 'instagram-feed' ); // verify params present (oth & download link). $post_oth = ! empty( $_REQUEST['oth'] ) ? sanitize_text_field( $_REQUEST['oth'] ) : ''; $post_url = ! empty( $_REQUEST['file'] ) ? $_REQUEST['file'] : ''; if ( empty( $post_oth ) || empty( $post_url ) ) { wp_send_json_error( $error ); } // Verify oth. $oth = get_option( 'sbi_one_click_upgrade' ); if ( empty( $oth ) ) { wp_send_json_error( $error ); } if ( hash_hmac( 'sha512', $oth, wp_salt() ) !== $post_oth ) { wp_send_json_error( $error ); } // Delete so cannot replay. delete_option( 'sbi_one_click_upgrade' ); // Set the current screen to avoid undefined notices. set_current_screen( self::REDIRECT ); // Prepare variables. $url = esc_url_raw( add_query_arg( array( 'page' => self::REDIRECT, ), admin_url( 'admin.php' ) ) ); // Verify pro not installed. $active = activate_plugin( self::SLUG, $url, false, true ); if ( ! is_wp_error( $active ) ) { deactivate_plugins( plugin_basename( SBI_PLUGIN_DIR ) ); wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'instagram-feed' ) ); } $creds = request_filesystem_credentials( $url, '', false, false, null ); // Check for file system permissions. if ( false === $creds ) { wp_send_json_error( $error ); } if ( ! WP_Filesystem( $creds ) ) { wp_send_json_error( $error ); } // We do not need any extra credentials if we have gotten this far, so let's install the plugin. $license = get_option( 'sbi_license_key' ); if ( empty( $license ) ) { wp_send_json_error( new \WP_Error( '403', esc_html__( 'You are not licensed.', 'instagram-feed' ) ) ); } // Do not allow WordPress to search/download translations, as this will break JS output. remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); // Create the plugin upgrader with our custom skin. $installer = new \Sbi\Helpers\PluginSilentUpgrader( new \SBI_Install_Skin() ); // Error check. if ( ! method_exists( $installer, 'install' ) || empty( $post_url ) ) { wp_send_json_error( $error ); } $license_data = get_option( 'sbi_license_data' ); if ( ! empty ( $license_data ) ) { $version_info = SBI_Upgrader::get_version_info( $license_data ); $file = ''; if ( isset( $version_info->package ) ) { $file = $version_info->package; } } else { wp_send_json_error( new \WP_Error( '403', esc_html__( 'You are not licensed.', 'instagram-feed' ) ) ); } if ( ! empty( $file ) ) { $installer->install( $file ); // phpcs:ignore // Check license key. // Flush the cache and return the newly installed plugin basename. wp_cache_flush(); $plugin_basename = $installer->plugin_info(); if ( $plugin_basename ) { deactivate_plugins( plugin_basename( SBI_PLUGIN_BASENAME ), true ); // Activate the plugin silently. $activated = activate_plugin( $plugin_basename ); if ( ! is_wp_error( $activated ) ) { wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'instagram-feed' ) ); } else { // Reactivate the lite plugin if pro activation failed. $activated = activate_plugin( plugin_basename( SBI_PLUGIN_BASENAME ), '', false, true ); wp_send_json_error( esc_html__( 'Pro version installed but needs to be activated from the Plugins page inside your WordPress admin.', 'instagram-feed' ) ); } } } wp_send_json_error( $error ); } /** * Whether or not it's likely to be a reachable URL for upgrade * * @param string $url * * @return bool * * @since 4.0 */ public static function is_dev_url( $url = '' ) { $is_local_url = false; // Trim it up $url = strtolower( trim( $url ) ); // Need to get the host...so let's add the scheme so we can use parse_url if ( false === strpos( $url, 'http://' ) && false === strpos( $url, 'https://' ) ) { $url = 'http://' . $url; } $url_parts = parse_url( $url ); $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false; if ( ! empty( $url ) && ! empty( $host ) ) { if ( false !== ip2long( $host ) ) { if ( ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { $is_local_url = true; } } elseif ( 'localhost' === $host ) { $is_local_url = true; } $tlds_to_check = array( '.local', ':8888', ':8080', ':8081', '.invalid', '.example', '.test' ); foreach ( $tlds_to_check as $tld ) { if ( false !== strpos( $host, $tld ) ) { $is_local_url = true; break; } } if ( substr_count( $host, '.' ) > 1 ) { $subdomains_to_check = []; foreach ( $subdomains_to_check as $subdomain ) { $subdomain = str_replace( '.', '(.)', $subdomain ); $subdomain = str_replace( array( '*', '(.)' ), '(.*)', $subdomain ); if ( preg_match( '/^(' . $subdomain . ')/', $host ) ) { $is_local_url = true; break; } } } } return $is_local_url; } /** * Handle API Response and check for an error. * * @param array $response * * @return string * * @since 4.0 */ public static function get_error_message( $response ) { $message = ''; if ( isset( $response['license_data']['license'] ) && $response['license_data']['license'] === 'invalid'){ $message = __( 'This license is NOT valid.', 'instagram-feed' ); } if ( isset( $response['error'] ) ) { $error = sanitize_text_field( $response['error'] ); switch ( $error ) { case 'expired': $message = __( 'This license is expired.', 'instagram-feed' ); break; default : $message = __( 'We encountered a problem unlocking the PRO features. Please install the PRO version manually.', 'instagram-feed' ); } } return $message; } } admin/Traits/SBI_Settings.php000064400000021625150515074560012126 0ustar00 'Afrikaans', 'ar_AR' => 'Arabic', 'az_AZ' => 'Azerbaijani', 'be_BY' => 'Belarusian', 'bg_BG' => 'Bulgarian', 'bn_IN' => 'Bengali', 'bs_BA' => 'Bosnian', 'ca_ES' => 'Catalan', 'cs_CZ' => 'Czech', 'cy_GB' => 'Welsh', 'da_DK' => 'Danish', 'de_DE' => 'German', 'el_GR' => 'Greek', 'en_GB' => 'English (UK', 'en_PI' => 'English (Pirate)', 'en_US' => 'English (US)', 'eo_EO' => 'Esperanto', 'es_ES' => 'Spanish (Spain)', 'es_LA' => 'Spanish', 'et_EE' => 'Estonian', 'eu_ES' => 'Basque', 'fa_IR' => 'Persian', 'fb_LT' => 'Leet Speak', 'fi_FI' => 'Finnish', 'fo_FO' => 'Faroese', 'fr_CA' => 'French (Canada)', 'fr_FR' => 'French (France)', 'fy_NL' => 'Frisian', 'ga_IE' => 'Irish', 'gl_ES' => 'Galician', 'he_IL' => 'Hebrew', 'hi_IN' => 'Hindi', 'hr_HR' => 'Croatian', 'hu_HU' => 'Hungarian', 'hy_AM' => 'Armenian', 'id_ID' => 'Indonesian', 'is_IS' => 'Icelandic', 'it_IT' => 'Italian', 'ja_JP' => 'Japanese', 'ka_GE' => 'Georgian', 'km_KH' => 'Khmer', 'ko_KR' => 'Korean', 'ku_TR' => 'Kurdish', 'la_VA' => 'Latin', 'lt_LT' => 'Lithuanian', 'lv_LV' => 'Latvian', 'mk_MK' => 'Macedonian', 'ml_IN' => 'Malayalam', 'ms_MY' => 'Malay', 'nb_NO' => 'Norwegian (bokmal)', 'ne_NP' => 'Nepali', 'nl_NL' => 'Dutch', 'nn_NO' => 'Norwegian (nynorsk)', 'pa_IN' => 'Punjabi', 'pl_PL' => 'Polish', 'ps_AF' => 'Pashto', 'pt_BR' => 'Portuguese (Brazil)', 'pt_PT' => 'Portuguese (Portugal)', 'ro_RO' => 'Romanian', 'ru_RU' => 'Russian', 'sk_SK' => 'Slovak', 'sl_SI' => 'Slovenian', 'sq_AL' => 'Albanian', 'sr_RS' => 'Serbian', 'sv_SE' => 'Swedish', 'sw_KE' => 'Swahili', 'ta_IN' => 'Tamil', 'te_IN' => 'Telugu', 'th_TH' => 'Thai', 'tl_PH' => 'Filipino', 'tr_TR' => 'Turkish', 'uk_UA' => 'Ukrainian', 'vi_VN' => 'Vietnamese', 'zh_CN' => 'Simplified Chinese (China)', 'zh_HK' => 'Traditional Chinese (Hong Kong)', 'zh_TW' => 'Traditional Chinese (Taiwan)', ); } /** * Return the timezones * * @since 4.0 * * @return array */ public static function timezones() { return array( 'Pacific/Midway' => '(GMT-11:00) Midway Island, Samoa', 'America/Adak' => '(GMT-10:00) Hawaii-Aleutian', 'Etc/GMT+10' => '(GMT-10:00) Hawaii', 'Pacific/Marquesas' => '(GMT-09:30) Marquesas Islands', 'Pacific/Gambier' => '(GMT-09:00) Gambier Islands', 'America/Anchorage' => '(GMT-09:00) Alaska', 'America/Ensenada' => '(GMT-08:00) Tijuana, Baja California', 'Etc/GMT+8' => '(GMT-08:00) Pitcairn Islands', 'America/Los_Angeles' => '(GMT-08:00) Pacific Time (US & Canada', 'America/Denver' => '(GMT-07:00) Mountain Time (US & Canada', 'America/Chihuahua' => '(GMT-07:00) Chihuahua, La Paz, Mazatlan', 'America/Dawson_Creek' => '(GMT-07:00) Arizona', 'America/Belize' => '(GMT-06:00) Saskatchewan, Central America', 'America/Cancun' => '(GMT-06:00) Guadalajara, Mexico City, Monterrey', 'Chile/EasterIsland' => '(GMT-06:00) Easter Island', 'America/Chicago' => '(GMT-06:00) Central Time (US & Canada)', 'America/New_York' => '(GMT-05:00) Eastern Time (US & Canada)', 'America/Havana' => '(GMT-05:00) Cuba', 'America/Bogota' => '(GMT-05:00) Bogota, Lima, Quito, Rio Branco', 'America/Caracas' => '(GMT-04:30) Caracas', 'America/Santiago' => '(GMT-04:00) Santiago', 'America/La_Paz' => '(GMT-04:00) La Paz', 'Atlantic/Stanley' => '(GMT-04:00) Faukland Islands', 'America/Campo_Grande' => '(GMT-04:00) Brazil', 'America/Goose_Bay' => '(GMT-04:00) Atlantic Time (Goose Bay)', 'America/Glace_Bay' => '(GMT-04:00) Atlantic Time (Canada)', 'America/St_Johns' => '(GMT-03:30) Newfoundland', 'America/Araguaina' => '(GMT-03:00) UTC-3', 'America/Montevideo' => '(GMT-03:00) Montevideo', 'America/Miquelon' => '(GMT-03:00) Miquelon, St. Pierre', 'America/Godthab' => '(GMT-03:00) Greenland', 'America/Argentina/Buenos_Aires' => '(GMT-03:00) Buenos Aires', 'America/Sao_Paulo' => '(GMT-03:00) Brasilia', 'America/Noronha' => '(GMT-02:00) Mid-Atlantic', 'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is', 'Atlantic/Azores' => '(GMT-01:00) Azores', 'Europe/Belfast' => '(GMT) Greenwich Mean Time : Belfast', 'Europe/Dublin' => '(GMT) Greenwich Mean Time : Dublin', 'Europe/Lisbon' => '(GMT) Greenwich Mean Time : Lisbon', 'Europe/London' => '(GMT) Greenwich Mean Time : London', 'Africa/Abidjan' => '(GMT) Monrovia, Reykjavik', 'Europe/Amsterdam' => '(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna', 'Europe/Belgrade' => '(GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague', 'Europe/Brussels' => '(GMT+01:00) Brussels, Copenhagen, Madrid, Paris', 'Africa/Algiers' => '(GMT+01:00) West Central Africa', 'Africa/Windhoek' => '(GMT+01:00) Windhoek', 'Asia/Beirut' => '(GMT+02:00) Beirut', 'Africa/Cairo' => '(GMT+02:00) Cairo', 'Asia/Gaza' => '(GMT+02:00) Gaza', 'Africa/Blantyre' => '(GMT+02:00) Harare, Pretoria', 'Asia/Jerusalem' => '(GMT+02:00) Jerusalem', 'Europe/Helsinki' => '(GMT+02:00) Helsinki', 'Europe/Minsk' => '(GMT+02:00) Minsk', 'Asia/Damascus' => '(GMT+02:00) Syria', 'Europe/Moscow' => '(GMT+03:00) Moscow, St. Petersburg, Volgograd', 'Africa/Addis_Ababa' => '(GMT+03:00) Nairobi', 'Asia/Tehran' => '(GMT+03:30) Tehran', 'Asia/Dubai' => '(GMT+04:00) Abu Dhabi, Muscat', 'Asia/Yerevan' => '(GMT+04:00) Yerevan', 'Asia/Kabul' => '(GMT+04:30) Kabul', 'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg', 'Asia/Tashkent' => '(GMT+05:00) Tashkent', 'Asia/Kolkata' => '(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi', 'Asia/Katmandu' => '(GMT+05:45) Kathmandu', 'Asia/Dhaka' => '(GMT+06:00) Astana, Dhaka', 'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk', 'Asia/Rangoon' => '(GMT+06:30) Yangon (Rangoon', 'Asia/Bangkok' => '(GMT+07:00) Bangkok, Hanoi, Jakarta', 'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk', 'Asia/Hong_Kong' => '(GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi', 'Asia/Irkutsk' => '(GMT+08:00) Irkutsk, Ulaan Bataar', 'Australia/Perth' => '(GMT+08:00) Perth', 'Australia/Eucla' => '(GMT+08:45) Eucla', 'Asia/Tokyo' => '(GMT+09:00) Osaka, Sapporo, Tokyo', 'Asia/Seoul' => '(GMT+09:00) Seoul', 'Asia/Yakutsk' => '(GMT+09:00) Yakutsk', 'Australia/Adelaide' => '(GMT+09:30) Adelaide', 'Australia/Darwin' => '(GMT+09:30) Darwin', 'Australia/Brisbane' => '(GMT+10:00) Brisbane', 'Australia/Hobart' => '(GMT+10:00) Sydney', 'Asia/Vladivostok' => '(GMT+10:00) Vladivostok', 'Australia/Lord_Howe' => '(GMT+10:30) Lord Howe Island', 'Etc/GMT-11' => '(GMT+11:00) Solomon Is., New Caledonia', 'Asia/Magadan' => '(GMT+11:00) Magadan', 'Pacific/Norfolk' => '(GMT+11:30) Norfolk Island', 'Asia/Anadyr' => '(GMT+12:00) Anadyr, Kamchatka', 'Pacific/Auckland' => '(GMT+12:00) Auckland, Wellington', 'Etc/GMT-12' => 'GMT+12:00) Fiji, Kamchatka, Marshall Is', 'Pacific/Chatham' => '(GMT+12:45) Chatham Islands', 'Pacific/Tongatapu' => '(GMT+13:00) Nuku\'alofa', 'Pacific/Kiritimati' => '(GMT+14:00) Kiritimati' ); } }admin/SBI_oEmbeds.php000064400000050230150515074560010430 0ustar00init(); } /** * Determining if the user is viewing the our page, if so, party on. * * @since 4.0 */ public function init() { if ( ! is_admin() ) { return; } add_action('admin_menu', [$this, 'register_menu']); add_action( 'wp_ajax_disable_instagram_oembed_from_instagram', [$this, 'disable_instagram_oembed_from_instagram'] ); add_action( 'wp_ajax_disable_facebook_oembed_from_instagram', [$this, 'disable_facebook_oembed_from_instagram'] ); } /** * Register Menu. * * @since 4.0 */ function register_menu() { $cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options'; $cap = apply_filters( 'sbi_settings_pages_capability', $cap ); $oembeds_manager = add_submenu_page( 'sb-instagram-feed', __( 'oEmbeds', 'instagram-feed' ), __( 'oEmbeds', 'instagram-feed' ), $cap, self::SLUG, [$this, 'oembeds_manager'], 2 ); add_action( 'load-' . $oembeds_manager, [$this,'oembeds_enqueue_admin_scripts']); } /** * Disable Instagram oEmbed * * @since 4.0 * * @return SBI_Response */ public function disable_instagram_oembed_from_instagram () { check_ajax_referer( 'sbi-admin', 'nonce' ); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); // This auto-dies. } $oembed_settings = get_option( 'sbi_oembed_token', array() ); $oembed_settings['access_token'] = ''; $oembed_settings['disabled'] = true; update_option( 'sbi_oembed_token', $oembed_settings ); new SBI_Response( true, array( 'connectionUrl' => $this->get_connection_url() ) ); } /** * Disable Facebook oEmbed * * @since 4.0 * * @return SBI_Response */ public function disable_facebook_oembed_from_instagram () { check_ajax_referer( 'sbi-admin', 'nonce' ); if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) { wp_send_json_error(); // This auto-dies. } $oembed_settings = get_option( 'cff_oembed_token', array() ); $oembed_settings['access_token'] = ''; $oembed_settings['disabled'] = true; update_option( 'cff_oembed_token', $oembed_settings ); new SBI_Response( true, array( 'connectionUrl' => $this->get_connection_url() ) ); } /** * Enqueue oEmbeds CSS & Script. * * Loads only for oEmbeds page * * @since 4.0 */ public function oembeds_enqueue_admin_scripts(){ if( ! get_current_screen() ) { return; } $screen = get_current_screen(); if ( ! 'instagram-feed_page_sbi-oembeds-manager' === $screen->id ) { return; } wp_enqueue_style( 'oembeds-style', SBI_PLUGIN_URL . 'admin/assets/css/oembeds.css', false, SBIVER ); wp_enqueue_script( 'sb-vue', SBI_PLUGIN_URL . 'js/vue.min.js', null, '2.6.12', true ); wp_enqueue_script( 'oembeds-app', SBI_PLUGIN_URL.'admin/assets/js/oembeds.js', null, SBIVER, true ); $sbi_oembends = $this->statuses_and_info(); $sbi_oembends['nonce'] = wp_create_nonce( 'sbi-admin' ); wp_localize_script( 'oembeds-app', 'sbi_oembeds', $sbi_oembends ); } /** * Statuses and info about the current state of oEmbed connection * * @return array * * @since 4.0 */ public function statuses_and_info() { $return = array( 'admin_url' => admin_url(), 'ajax_handler' => admin_url( 'admin-ajax.php' ), 'supportPageUrl' => admin_url( 'admin.php?page=sbi-support' ), 'links' => \InstagramFeed\Builder\SBI_Feed_Builder::get_links_with_utm(), 'socialWallLinks' => \InstagramFeed\Builder\SBI_Feed_Builder::get_social_wall_links(), 'socialWallActivated' => is_plugin_active( 'social-wall/social-wall.php' ), 'genericText' => array( 'help' => __( 'Help', 'instagram-feed' ), 'title' => __( 'oEmbeds', 'instagram-feed' ), 'description' => __( 'Use Smash Balloon to power any Instagram or Instagram oEmbeds across your site. Just click the button below and we\'ll do the rest. ', 'instagram-feed' ), 'instagramOEmbeds' => __( 'Instagram oEmbeds are currently not being handled by Smash Balloon', 'instagram-feed' ), 'instagramOEmbedsEnabled' => __( 'Instagram oEmbeds are turned on', 'instagram-feed' ), 'facebookOEmbeds' => __( 'Facebook oEmbeds are currently not being handled by Smash Balloon', 'instagram-feed' ), 'facebookOEmbedsEnabled' => __( 'Facebook oEmbeds are turned on', 'instagram-feed' ), 'enable' => __( 'Enable', 'instagram-feed' ), 'disable' => __( 'Disable', 'instagram-feed' ), 'whatAreOembeds' => __( 'What are oEmbeds?', 'instagram-feed' ), 'whatElseOembeds' => __( 'What else can the Instagram Feed plugin do?', 'instagram-feed' ), 'whenYouPaste' => __( 'When you paste a link to a Instagram or Facebook post in WordPress, it automatically displays the post instead of the URL. That is called an oEmbed.', 'instagram-feed' ), 'dueToRecent' => __( 'Due to recent API changes from Instagram, WordPress cannot automatically embed your posts.', 'instagram-feed' ), 'however' => __( 'However, we have added this feature to Smash Balloon to make sure your oEmbeds keep working.', 'instagram-feed' ), 'justEnable' => __( 'Just enable it above, and all your existing and new embeds should work automatically, no other input required.', 'instagram-feed' ), 'displayACompletely' => __( 'Display a completely customizable Instagram Feed with tons of features', 'instagram-feed' ), 'createACustom' => __( 'Create a custom styled feed of your Instagram posts which integrates seamlessly with your WordPress theme.', 'instagram-feed' ), ), 'images' => array( 'fbIcon' => '', 'instaIcon' => '', 'image1_2x' => SBI_PLUGIN_URL . 'admin/assets/img/oembeds-image-1@2x.png', 'image2_2x' => SBI_PLUGIN_URL . 'admin/assets/img/oembeds-image-2@2x.png', 'image3_2x' => SBI_PLUGIN_URL . 'admin/assets/img/oembeds-image-3@2x.png', 'image4_2x' => SBI_PLUGIN_URL . 'admin/assets/img/oembeds-image-4@2x.png', ), 'modal' => array( 'title' => __( 'Enable Facebook oEmbeds', 'instagram-feed' ), 'description' => __( 'To enable Facebook oEmbeds our Custom Facebook Feed plugin is required. Click the button below to Install it and enable Facebook oEmbeds.', 'instagram-feed' ), 'install' => __( 'Install Plugin', 'instagram-feed' ), 'activate' => __( 'Activate Plugin', 'instagram-feed' ), 'cancel' => __( 'Cancel', 'instagram-feed' ), 'instaIcon' => SBI_PLUGIN_URL . 'admin/assets/img/facebook-color-icon.svg', 'timesIcon' => '', 'plusIcon' => '' ), 'loaderSVG' => '', 'checkmarkSVG' => '', 'timesCircleSVG' => '' ); $oembed_token_settings = get_option( 'sbi_oembed_token', array() ); $saved_access_token_data = isset( $oembed_token_settings['access_token'] ) ? $oembed_token_settings['access_token'] : false; $newly_retrieved_oembed_connection_data = $this->maybe_connection_data( $saved_access_token_data ); if ( ! empty( $newly_retrieved_oembed_connection_data['access_token'] ) ) { $oembed_token_settings = $newly_retrieved_oembed_connection_data; $return['newOembedData'] = $newly_retrieved_oembed_connection_data; update_option( 'cff_oembed_token', $newly_retrieved_oembed_connection_data ); update_option( 'sbi_oembed_token', $newly_retrieved_oembed_connection_data ); // If the access token is new or has changed, then we need to clear the cache. $this->clear_oembed_cache(); } elseif ( ! empty( $newly_retrieved_oembed_connection_data ) ) { $return['newOembedData'] = $newly_retrieved_oembed_connection_data; } $return['connectionURL'] = $this->get_connection_url(); $return['tokenData'] = $oembed_token_settings; $return['instagram'] = array( 'doingOembeds' => $this->instagram_oembed_enabled() ); $return['facebook'] = [ 'active' => class_exists( '\CustomFacebookFeed\CFF_Oembed' ), 'doingOembeds' => false ]; $return['facebook']['installer'] = $this->facebook_installer_info(); if ( class_exists( '\CustomFacebookFeed\CFF_Oembed' ) ) { $return['facebook']['doingOembeds'] = \CustomFacebookFeed\CFF_Oembed::can_do_oembed(); } return $return; } /** * Clear instagram oembed transients and cache * * @since 6.1.2 */ public static function clear_oembed_cache() { // get _transient_oembed_* options from wp_options. global $wpdb; $table_name = $wpdb->prefix . 'options'; $transient_options = $wpdb->get_results( $wpdb->prepare( "SELECT option_name, option_value FROM $table_name WHERE option_name LIKE %s AND option_value LIKE %s", '_transient_oembed_%', '%fbtrace_id%' ) ); foreach ( $transient_options as $value ) { $option_name = $value->option_name; delete_option( $option_name ); // find the _transient_timeout_oembed_* options and delete them. $option_key = substr( $option_name, 18 ); $timeout_key = '_transient_timeout_oembed_' . $option_key; $timeout_value = get_option( $timeout_key ); if ( is_numeric( $timeout_value ) ) { delete_option( $timeout_key ); } } // get _oembed_* options from wp_postmeta. $postmeta_table = $wpdb->prefix . 'postmeta'; $oembed_options = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_key, meta_value FROM $postmeta_table WHERE meta_key LIKE %s AND meta_value LIKE %s", '_oembed_%', '{{unknown}}' ) ); foreach ( $oembed_options as $value ) { $post_id = $value->post_id; $meta_key = $value->meta_key; $meta_value = $value->meta_value; $meta_value = maybe_unserialize( $meta_value ); delete_post_meta( $post_id, $meta_key ); // get the cache key. $cache_key = substr( $meta_key, 8 ); $cache_meta_key = '_oembed_time_' . $cache_key; $cache_meta_value = get_post_meta( $post_id, $cache_meta_key, true ); if ( is_numeric( $cache_meta_value ) ) { delete_post_meta( $post_id, $cache_meta_key ); } } } /** * Connection URLs are based on the website connecting accounts so that is * configured here and returned * * @return string * * @since 4.0 */ public static function get_connection_url() { $admin_url_state = admin_url( 'admin.php?page=sbi-oembeds-manager' ); //If the admin_url isn't returned correctly then use a fallback if( $admin_url_state == '/wp-admin/admin.php?page=sbi-oembeds-manager' ){ $admin_url_state = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; } if ( class_exists( '\CustomFacebookFeed\CFF_Oembed' ) ) { $cff_oembed_token = \CustomFacebookFeed\CFF_Oembed::last_access_token(); if ( ! empty( $cff_oembed_token ) ) { return add_query_arg( 'transfer', '1', $admin_url_state ); } } return 'https://www.facebook.com/dialog/oauth?client_id=254638078422287&redirect_uri=https://api.smashballoon.com/v2/instagram-graph-api-redirect.php&scope=pages_show_list&state=' . $admin_url_state; } /** * Listener for retrieving and storing an access token for oEmbeds * * @param string $saved_access_token_data * * @return array|bool * * @since 4.0 */ public static function maybe_connection_data( $saved_access_token_data ) { $screen = get_current_screen(); if ( ! $screen ) { return false; } if( ! isset( $_GET['page'] ) && 'sbi-oembeds-manager' !== $_GET['page'] ) { return false; } if ( ! empty( $_GET['transfer'] ) ) { if ( class_exists( '\CustomFacebookFeed\CFF_Oembed' ) ) { $cff_oembed_token = \CustomFacebookFeed\CFF_Oembed::last_access_token(); $return = get_option( 'cff_oembed_token', array() ); $return['access_token'] = $cff_oembed_token; $return['disabled'] = false; return $return; } } if ( isset( $_GET['sbi_access_token'] ) ) { $access_token = sbi_sanitize_alphanumeric_and_equals( $_GET['sbi_access_token'] ); $return = []; $valid_new_access_token = ! empty( $access_token ) && strlen( $access_token ) > 20 && $saved_access_token_data !== $access_token ? $access_token : false; if ( $valid_new_access_token ) { $url = esc_url_raw( 'https://graph.instagram.com/me/accounts?limit=500&access_token=' . $valid_new_access_token ); $pages_data_connection = wp_remote_get( $url ); $return['access_token'] = $valid_new_access_token; $return['disabled'] = false; if ( ! is_wp_error( $pages_data_connection ) && isset( $pages_data_connection['body'] ) ) { $pages_data = json_decode( $pages_data_connection['body'], true ); if ( isset( $pages_data['data'][0]['access_token'] ) ) { $return['expiration_date'] = 'never'; } else { $return['expiration_date'] = time() + (60 * DAY_IN_SECONDS); } } else { $return['expiration_date'] = 'unknown'; } } else { if ( $saved_access_token_data === $access_token ) { $return['error'] = 'Not New'; } else { $return['error'] = 'Not Valid'; } } return $return; } return false; } /** * Check if Instagram oEmbed is enabled or not * * @return bool * * @since 4.0 */ public function instagram_oembed_enabled() { $sbi_oembed_token = get_option( 'sbi_oembed_token' ); if ( isset( $sbi_oembed_token['access_token'] ) && isset( $sbi_oembed_token['disabled'] ) && ! $sbi_oembed_token['disabled'] ) { return true; } return false; } /** * Check if Facebook oEmbed is enabled or not * * @return bool * * @since 4.0 */ public function facebook_oembed_enabled() { $cff_oembed_token = get_option( 'cff_oembed_token' ); if ( isset( $cff_oembed_token['access_token'] ) && isset( $cff_oembed_token['disabled'] ) && ! $cff_oembed_token['disabled'] ) { return true; } return false; } /** * Determines what action for Instagram should be done in the following order * and returns data used in the common "addon" installer * * Free or Pro active, do nothing * Pro installed but not active, activate Pro * Free installed but not active, activate Free * Nothing installed, install and activate Free * * @return array * * @since 4.0 */ public static function facebook_installer_info() { $all_plugins = get_plugins(); $active_plugins = get_option( 'active_plugins' ); if ( in_array( 'custom-facebook-feed/custom-facebook-feed.php', $active_plugins, true ) || in_array( 'custom-facebook-feed-pro/custom-facebook-feed.php', $active_plugins, true ) ) { return [ 'nextStep' => 'none', 'plugin' => 'none', 'action' => 'none' ]; } foreach ( $all_plugins as $plugin ) { if ( strpos( $plugin['Name'], 'Custom Facebook Feed Pro' ) !== false ) { return [ 'nextStep' => 'pro_activate', 'plugin' => 'custom-facebook-feed-pro/custom-facebook-feed.php', 'action' => 'sbi_activate_addon' ]; } if ( strpos( $plugin['Name'], 'Custom Facebook Feed' ) !== false ) { return [ 'nextStep' => 'free_activate', 'plugin' => 'custom-facebook-feed/custom-facebook-feed.php', 'action' => 'sbi_activate_addon' ]; } } return [ 'nextStep' => 'free_install', 'plugin' => 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip', 'action' => 'sbi_install_addon' ]; } /** * oEmbeds Manager Page View Template * * @since 4.0 */ public function oembeds_manager(){ return \InstagramFeed\SBI_View::render( 'oembeds.index' ); } } admin/SBI_Response.php000064400000000720150515074560010647 0ustar00'crƪmY`dUSaCL?Йn˲%sU8ϹG{jO?G{qŸ>0jo=Qs"j1uUV43ȃw{8ʿ\bq VyEJۊ-h7z~ܞi: 2C嘙8V}o7xf^Xz= hH4P@ݨxƇ1Rx:]MM~hѹVn_Tųql<؈cG Lm/ڛYՎE}q,2L W|"ge{,j8LPp*q7uRPFcB0 n5Nۃ[YSU1*Yr\. ,*BR@|emhC0DroQ>?9w^\(t?~Qi ]Ak3Qi [e_MlQ<PxI Y4HXXTр|O,/#VC3|}:4>~6hl% Nwb'3ʾDl}6| [MegbV=M{f\j7 c1ޟ6Z%&ɴh~󦆍ӰG^F!cCn>#e,oby/cpugW9\v;Zimm-Fy( %0A# di/--MKikeNBAZIGI II_ 77w9<&]T Y,ݤ7ڹάT* &F% f25r(h@)RR*MAxAXnE텁 2 0 y#sjO՜nr@< iUmo"P x,i٨.se&07Gʱ * E 5#Ϝi%&b$@LDb{gR+hy9IJU}GY?+>@*@;Ox<6O%rH Rhh;4fc-DDrLqRRpYngGU#YFQ@,199jjY_H0O. _޴(Բ5y.FroORq̸O>KD^KG>zߵq{S jUN.'f6I p@b / o.'"2A(\i}9!J <|# Y|ddd]K.mQu4ЪA"iab%// RqT<|q:YN=aDM R(DԒڳq-@ҹ,tA ȑ]PQ.lZ}RK-{k[k8|UġmO P$ EU 2|=ddmFJV} RHH. sln qaO2q-/e?v\ֶ',!AE"KhߴeИȻ(7(yTvSUQ`Fkqeq7rUWCD90p+laچh|e.nmXsuuf3`\4{504P{ 2%.kNuM<lͰnkx*"G6'"DN~|:2iB!9ZBN#TR|=r+B>mʈ;ŁH9$f]16 vw}'ys^ɓKjup*4 9ji44$9,5$((d֖m|mY\6a\VLU5qɇt駣ř%%@7DLM _"ºi"B\儋ǽG 8?559;;yTMZ:=30zVQFN]>TՕ1Z<:ZYY;zɑe KSL D =EfXN']g g"4:$9528%Gٮdu-,XWt,JbsۛKM<{HC1I [Z#񃺯$C;٧ *,6!)8]?w ?*%X{>99;ńIh%ߢ#d2T4:;TQTY\<4ddr %)'glhZ(T3Z/ZMKBuvvb`q(<rh$8jEq5>%{uvwu!N߀`Awb*픓 H`XԎ&Ḿ5BtJilE)t^-/k\y;UwjU+E"֠"++>t8,D4>?Wy,OV .SBqŋmlӈf=ϕvzJ/[ ib]>v17>*us؜̹,6ǮbΜ0N`r̍FZBKmZ(qRUhi2yDjHiK.~#+,XblϯkLݺn%ӎi'='HԾX 4EUUlJjuRD Lfڑ#Q .9d&D& R=]/M =r~o{{',XWW}U~l}},`+`12χޠVT"BWG$I{WIhF#8$%<9cdddI}hjld2/٭z[-z-˗ ܏ի"vrS"+ h rjy V{Ҹ{WNL3y᷶.)=I0۝Y>~}%#XfovvNT:EU ʙݝ=A5MbPw<i4$(ſPZuj x($09f-t U11111G:QTYg.x?bZ5N#ر̬> | )Nf@_[S PHHt1 ʮ53DŽT97L02_NȈJ,iszz:XM/8D4@%AE"MMMMWƥoOftw-͒-sxc ͑U&[y]Da!B"lQC:t0SUbr*"`;[eeu1M/8$<8X8⸪/艏?Ͱ^bf4ݰ- -^ܓqh|Yd3<01ryU~`\ 8 Os8dQ ޫ3sNB%Vf??^cRS00cHMY&$TL$LǴ@+@^!$G@-8ϔ׉qqg)mLg0ѸAi7y omvGah3kdT̰i "$+)2$p/<]bPHhu8|Pb?%Oc{wf\ P;N]A^HJq%2Қg5T"PЋZY, %;փ~ /|ǢGl9sNm}6bh6;nz}2+.^ egyb5N;V@ D[; %d~a HT5WZp8` Qt[AetaqL{y\2"!.33J%!pyRW'azK#o!!u֭ۯv,_bSn9 Z 0^j l ߸šAx{Wr2.ϓV'N~%cd~>RRR"`ƨ#p4uy{ d}/u4G^*<@Zۅ8~6AV*%&'B=B(ZI*9kuU`4ǔQv7:f @:gY6qm-p8>Dg&O{BIK].Օ;#ܭ1v Euy 4tMpqSɶ%Xā t긩TugU!jzb8(9dGߤ@W|6֌8qp,ss@\g r  sY$!MawF#"-1 _|;cV(Kc?n΁ 7 ӽ{mM8 +!!@R0RكgϞ]- ak?:@Bȟi 9b2fyy7/@@ڮhGfQ&PրdwQ+CCE].a& 8 8Iv2E?wB "Hj[b  Fpxn-U߾ʬnѫ p0` @'`GG[7{_oDG0 w" _gozug&,R?H )L̤(^>W@"[E%x<`u& uC w[}\wk<=s."bi `<Օ5*^W2HƕZ*"Ð\Aap^;`^hGw wՕꍛkF{Y}Xԟ„O>]V֣׳s}h}w}(ĸ0fIENDB`admin/assets/img/fb-icon2.png000064400000000434150515074560012030 0ustar00PNG  IHDRW?9PLTElljklkkjkpkllkkklk]UtRNS`@pPϠp 7IDATeW E'U/v$ z+c_0rJuj_MTOL%Tl7M': 1n@ylG]8QOi admin/assets/img/cff-sprite.png000064400000007654150515074560012506 0ustar00PNG  IHDRZ2^PLTE@@@ڎ,,,tttê===ˀ888ک[[[ƞ{{{@@@mmm䳳TTTȋ444888CCCZZZ}}}AAAkkkjjjYYYF***AN jYr>μɴy\ ůggg97ǍtRNS% 3f,;TY!Y?I DfoNq8ݙu3ߎk޷njiyึvq(ۚ`Lؾre Ǿ}waa_\aC6ųpeP9/!1}&q hIDATxo@pS4N$I@*[D[{)!KNĩJ*@(T>00v< Sw[KkF`&ɑ\AhZ*ap,&Vb˂eœž\K_q'C'/m jjl PYO SjBaȢ&IR!V|o샯[l />m ٨ I`K-)u)Yp7d M!4}9;nɀP:O%A|CG2g>23p4<P=ù8´v"lgGJ1wC+J*DGVhS6\ĸg͔? ̐&fB-7BzC-FL9J aB@`"xNr5Mmڙ ApLv>kicWl絴 y:ǟWa4gClpq} {ړ8Y$zf4͘jr`G[ڹ2AeSK( 'ԧDT"P7&e0=14s; 5fC*$laXGye2 W@&ݘ<͆#OmGNq 8φ^3#Jx|ߋ#ڧ L^&T*ɠNZ[EqqQlR+ zw`-SG I  JFBv N@Yu8S93_lԂ_t Y  G+o YF1.âϧ6a5v.Q:ᣮAׇ0JU.?v\ܴ*-e,lbՔPDB<-´xZ(:[KOC3mrx {Xd3㞞,v;Ѻuv[fxfp@j6<0/YW{ƄH>xjo&r<6y0)qJ; П2z{An8Bޏ&&2-¸ f6E43R&qr2"0>c`L)Y)@hC #k&l% 5(eSR)AuoC#` Q8W!s}ڼB{#J0 "yi+zfZAxo0'%38HKeKp{Gc$]M /O: N2$NCT0K 6p@Lu&@[{ C=qbOLY)`TE4]Rd3BY_>B|8&pkgG MJ opbcj*?SBSuZL|+XƄPAw|`:ב<Ʀ6~\c@,ߺ2!RSp sFpV] N`oX8aH/vo?#9Nٽ1#&h6vls1$ˆf9NeC|Bؑㄹd @?x7_4৘ӄ@A0ă??)zi MV鈒$.̤33F< < $$zPc }9ti&&˶?k- }\ȇnT?̼B  p>,kĝ:v w~Duw5\é1pԂrp_ h7p <g;0q+ч-? :NQ`\?8P&g_P9[A;hk:\\?XL3?qtmtvᰳtt9X!>T?ykMUbC=t8S;:C4ԞC6n-uhp:DP+P?II$JV\@Wɰ]H׉q޻`#`dH*%٠D+sW)K8f1m0g6Q Ĵx^ (9sb᳼ tFF#7l%6h\$7|8-P,ҹPtj:4Gx4s2d0ymsesm,++RTh%Zz8Q:Ϛӣ`H<ǖ77cI(,WWUZ K#x%k.0 ncv2oRL*X\_:h{9p:`Mn 0lɅBEr]g쭀}oRxX|1-cQ2*eyKW-Yt5~?ƞoGD,i[YJ\ OEt bȐUQd2;q:-phBb*- ATr7QL`ks ?@~}ӡٵ5ߡ ]Nm :ThQ? \:@]mFtSkr;-ҋ1p8mU ~X'z;tTZoZ>p R^(oIENDB`admin/assets/img/insta-icon.svg000064400000005625150515074560012517 0ustar00 admin/assets/img/instagram-with-uncanny-automator.png000064400000043572150515074560017063 0ustar00PNG  IHDRtPLTE}LbQ]?R[e}xzHaPkMWW2I?^~z9W[DYj3Kf~e1L_/@>^tD^`.E9U{XsxTpe,I:Z~Miq=W^c'Gd&GFbJda!GRk=V|Ea;\HenIeɿ˞wZEaTO-9VUP$2UQqvm2]*4M%.@Q.H;(o-emYW#!z@Gѽa9R߷؁/*DYjo{VcteU w䕸ߜ|Wsf}{lke$txh_Y#޳UhcK1qkOWT~.C<+˶GPF|?bOތFt=kI'Ьd;뜻EYG®!c䄶ypȶ?Gm^h|0FtRNS  %,)$#!'xIf`@6v3̳HU6Y0CIDATx:X0|.־ FŨM"n}2y(8 vtVĈ ?QT+}23@a&Ù 7Y CYT]_㬮.ܠe]~yBU8r3 ˺z\wD䰶OSµc+_KS;$o)_ƅ۟y <i#_9{=,x25,ĭq 1nIe:.4^^s=C 0. AY +Io#j;KoKv"0jyi}q¸7^;"DAPO!DB(. emq4B<=%r.wŽC*$3;LxuD~fkve\ BDYOCUK9pRɑCۣ@TF$RH_U?x浕DaX_UXp !''D ƈ*uc갭Œ`̫4s-G ɽJ"ɩqeoZ( h qqV9G9@3@dLKvz/\:ak3fǒLl!2 V8sj&ȶ6y40x*:@w$[˘Q#9Ygme2!SEoswݓi#Fiل8 xҾ_ёڥxH'xh@J1+1cjVFomؑ>CԵwp4\l^̆2\ZXd{F91{X=9xVژiG {i(dzxKuFxDB3yxf3FEPNߗB0̹/IR0DtfRe 6%k"M!fǓujDbV7SI Uxs_3B@T c;MN\/׾!Z!ٹ JdE#tLYTO~)B;;}r[RPc\ٔ-x z'3)q֐%)Ě26\8foi 8EfmLn۸֦WBǓ~`BLR0\Ɠg.`GE"ts1&q.lٓwFy0L:C]Y!pE1:8 }(q(E&Pinu FL'3fjzTe޶xr&R%x/_,]sI8mEڿHW6|n}.ҟú/e&%K#rzMq4Z81iHN 3`@ 1-Ut\.ҕeᙪo> AVn]N6h$G.ػ9#&$tj"4-w{\ś7[ɦ~obR1{n *۽4qa534Lɚ;/~.o4tdhxxxXwWpG8K06bO;=_}ZV/..E͐QX/nN&suF1<%ιI<ɘAEsEװ$s4am!5 mh jF,{!q?E/ sȈah683>鵄:Q 2D\;fiNgCfJQ5)*|YXs)K<1q wc ll￿V~|kk/CEf{)߯/.ׯ?}|æDůFsyTF]-h4"hLbtYU甉-ZYڍn[8Bn:u Fy9>ֻ^=s/!}9ϡF)6d bƁ:W_}ݻwܶmKP=ܹ?&dw<!r7]Z¹*>&]]қW ”/@-:H({\ h`FT!0m]ۺad<+1B?ji ?KcƋ[6q=T3;ܮŸ`ByV,0#"),GF@̄Q+:ۄh"ܶ4h8vF ۴+;o ewKlrIWT ȈQT!al_ җA`co>ݻiun-ٽa)ty._!+)X(ȗT%]Je?a/uk_lqw w_|P{s"cW1^Kojw--)9e]ZD dz7ٿ"<%[n O^UiXle`*-R^@JN:p $"f-B%WaGdkծ1v K 8O4!\)FxM!jdy/7WeX215-GK|~{*jm ٙ^1Qo@ m_`k"\D +Af*)BDhM8K5uSeF-GbV=LP' ;AGڅUF#tX`EliX{)|[ q$_`!\40zlv8P)$ ýD8kL8pZ+]E\Q^Rs8 Nd>E aV3+B nm%U -O44Hџ cZn٣ ӫpyd%G^Є\R8|d#>[ 7}TjW[ <` \I/^q2_>FαdnjVEBs1˦6\b~F/œG=8r8&a1WC~w#1㭜a=-ljOqd O`!+ĆO^uĹO'ٵk胉O ]RDBܧcd MgFb=p /k9@o@΋NE|Qa9ZфA`k:a}xޅGH]E?kq\ul!t /8en$<,u j9gy^34.MwOQWo|N8Q:|RY(O[#S'LˋLuW۶!۰Z'K0f/F #_!CT:)/_t0[RT" pH Y =HC,4S%RMZٍ屡|eK]Ѱ&,$2iYO? yvkLWҡH<'|).֝& djtS 2Fh\0?|8i{)_؆]; 4b~L=}K '֣N<>l8 Y8[[ fCjZx{/O1LgSt0Exi*rC,_yKRd`xz td3WcJfhb 1Ș"~dWV{Q~`,owoum{(,$@-%Oo"k #\F"h_`kTD/g`,_ CDLD#0V?y-]v+9iE4ɒ7ZM=]-8x6Rg:`ly/:EA8ኤ5*8_A8)$j,.#ks056r2Z!F۲r8嫿Z ^:[ݬl!Q4sN 0Z3jBT9πh<10^1~9BBOdU䪱%a`(fZcVqew0( RpB/w21ryO|(s܃v jٚz ?vwcoh2r]/eɃas 7?ȗM>oӠu0x=6sAV=c\Ϗ>xrS\&Ku:IܻxqnnWv!ZG<+7Y7n8nZPe}L=[_*aWAZ\\r=ў=|>Q`s.%l36<)9ᦫj!KͲ[X .SzD ,}2(L7/| ۖW^0x,-G{&usVGg(nwo4IGU kqׯXUL*qu˯@ 1qx6gk0`c5>޿BMqk"1}5_%Dը5W/.Nhoz<>H^;r'#Ǹs!+rqs:q'sT?JN3\6kF,7\3^a9jE,6f|\a `̂tߥ`'Xb]0y77-*'պ%;` ҰxDqEi$W^pas&+`Ѡ kd-ӏrXI|3K̟ wŴYqܗ@ciίi~KI$f 8'Uh4)mhF iH!E H:a̘9&^kyO@˗v5pt44Hrpsv{ VdzW~\|tZ _Вr䞓U()ͭ7hq:B{0_#:953~LU~݇ rEta~yLk$˗T],IctGz˜jc|`˰R1 Ht dːߓ?_/]Cl.} v$V܏jj:|kJ/5{wLX -oY'®ΰm*:,ZT h'RByk؅97T3ظ[FM1u LtA, |hzf \Xe.\t $ 2OЃFZ'ipxfE׫!VѨAx\ T K0y5̓oc & x#וv6O 3k"tǷoFŠhnCIQ0ʢݷ>\)b 8V颥_/L++ 8T ,f "Dm_X+Đ39~o!aog"<99ywF{/w?i SOC'4݀͆t>!A<')aӀ'*_^3MMȣ;΀3$i$[8_gGhm{#v(H#l;öm*`_@W@yZ>/jc|YYLn\.X<Sh",%N{TE#r !ΔZT+lJq&PYx]/[Pwۅ}ÆۣOE_U/w "q_闙/_bFDEE~)áEEePڽuy" ™CLDl"D8&&5؉Gmαn 69pgoܸq;wx[OV54{ίH,-wUT $=[GR``Go-.{-jcA;D8`ab8xew|P+c $\A5ϩ$B:99px +ƅ6wrxx&·;4l6gN+J(2Rt 9ݰ /:Uzɮ.7IA wv3bx$==B8MDp >[eRme{܁fq1Ol]^-mT[T11N_kiil`liiOmÿTAP[7B!T*^;ʗ:C8mD}iۅXIt $*r4OX6Xl#^U]]_Dgz"Ɋĝ/hyyC҂|@RC/{Z'>t%ԀI<8 n&<:+HF^ |v9KW6=B[tݷWqPZ …$\z2.º 7"F/)7 +X,Ω5>65Pv jm[9#c`#T[eJQKlvޱlLi/|,bwM5D7wa5`h#if襩!2VFׯ٣NkM؜Ze}`ԱT,Nu(E &ife2n(¡Y h;V;ek528i u zNν.u|/XJJJЩY䐃ȲP븭,W 2Y:/,L5 6iŤ٩.Ayqnev5K i?HeԱciъH@Fw?SUG48f^Ŋ1`@ T4 'a0[ۛ ` vzb' k:|SroفZ8ꁘg⌅]:$ZRw<=8S4!p)ۿ[3KYt[_wrb :AxsB1فGK ˩4n*sUx|CQ!7 b"ؔ ۴%bޤȤ\!egy9R4rh<ͤuzh%vnE]FJ42gT<|I2'L* XkO:g&r,30Wcb(|w*ʽC*a-@K@Uu hGA^FipOΦ7#8  Vhe+BcrHH~@nism]޷9OjzzzMU_F7M1? Y%Mr#ѠkM0߿w}7i%P&lZ63Rm;ج| .:H4%\Y.[ DϰkcCgXT}~VjFW1ͳhXv6js[jv(aiӸ&>b\ogݘLdX3 ) eG9izH'v^}G#m`9m6J `;Na v F|װZ y4fJk/09Nq5?%&&f;|/\XPi3>s/G.G{72qRa#@V0Nr.mkS 8+5'YO@{1P71{ EO&m"$3<,;@Jc lSuY.V~wc^;0>=f h\DzA89d3#q՜#w;uIc5t)hEhīeL`Z::vlM{>}huQg$\S7 ê/Z1DU]X̊6Mp!: Ώ pdXZJ[Y^$`ex#o^vd |~e%ދ)^cxaQYQ73W9ر!ܫnh$!KV2O!Q8./^Mm`p@%&/Lc*؅`]C5_Ix4La׈&5P:n{/ek};_fbWAzK%%̈́ph&M #O1v+D `1\v$;Y(Vp IA-1ǀFĺp<qnK/Ԗҁ0ڱ> $ЪaV??5u/Q  CXslD18-$8#ft]ЀYN z0 O[(a1W+ dFˋ: q{t"`#TItwTp:]nTlܵZnVO yfI'JXΞ[`G7AUo +xH p*3fE?Ȇ>$\3?I,^)- bF,EE#fXc$w/v(+ٵEpy Ytڪ޶{FT a, ܾ$LGn!~ b|͎heDl~faB|pdqh{͍z|X Go̠CRzA&~lD/CɳXfjіIA&[iQ$ s77^1v%N3*D~TΙWk8 QTϘaL&)%yR<1ELBg>xRڤ)r ]ɮd Bfxdna&g'LŬByU/jH8N0Za <4\!?{%x02*Z@ô9ەQdҬ6{j5;t2#6ZW$Ju|oL'gaI5K Z2B ϲA2DL3!mԪQh4Ɣo x],R XbpxE] S@)l衏S} T,p͇I;|ުυ;sMtELgא~9wh*o56s-Dm k; -7(< V3f2X%v~` Cr"j7u X.8KjلzX_D<Y3{a.o/˓$3LCNXH7T~:[&Z2 X3itTR"v5%…ɲ%gu}/Ջg)T{w +EHl:a!o]c3 ~;w3|[k)#U2yOH!XYЋ&p^*/|p'B&QM4mcq BïݰG_h]#"WþVoXlUm+KF=A>65ѼwE'_~G}>ϿZl :5o* Ǎ7 `aC#A}~3~|)oݨuK&h߹]ѺmfoSצfߍCpw4K].2wv+(!ڶ[o`= a}R88{1܆\3&NI'gpJXVpHW4{1\z1ep!~?#0/ᕚVP`9U!\"]#7dqoM9Ϗ19L;Y yd/A-poP 7R/hGc1[y1x]۶?oύXMgIL6^A?FfZdή^qJI?~ƭeq/mѧ1McWvoss&gq{S mC^Qz0c$X1j.WSK7t 鿾GIXU3ӈzs Vf;`L_s̛ ۝meƀfms6fԽNh:݂. .,j:^)-]߆*ɏpT!DN70¹Iz~Z6yscV+L= VۉM;;WuE\ЭoBxe:*d4U@4WijU7K^* 9H_7dZs{硺5ack`W dt\e;yS,om*wq+yyܞ(v)h*tO:ցmh 6鶜KJеkSibP5xǮ 85 _'twun 2Izށr%`hub:E؇кw$\N>=9~oDKSw={1] kJj)Z fy+IșVFPf(pe|ce|zɞǶqrfY|}끕^tswoY3u>9[ZPG QOvjΚv@5 \g[L$:E6Sq`QW{u ƾ fbqN?f]մE89ҰFf6dK5X7B^\ͭfm;&%)sh%ftAoUՕ4i^7.zU3,T.eUhM!ԣ||E̱8|j3!Yx{S%33o}/ռa]+PSjgQjyʉSi'YSM]BTyy}.ʢ9-%aegYv(6I8aElrPHy̼;~6SM[u-TFĆ.խoiZp}aL='h'Gkem]zԾmh0hs.Rf̹r=t F.!;pXGsL4ikv9ۄnXٔ^s=Ky P09ʨƩIܴnճh]pZ/ؾ\쉢տB6u1.byP$g^f`ic|X$T - &/usEtqM\_=t'==-/|$ ǹd:8#LvHg,oQ![::p-B\ULٸzP*N>q2d-ˌ)j"F#˜|{g5 Q}Mq93 BlG Y<`ּG[X! ⍇WH%2bGxkWNY# 3``{^'B<4eΝ ;xx=XL_R'#PO) a,?$^+B) 簂G{rkCo2U}2sE SŖD !bOAθgToܔ>t>DLMvrUka&]kq/p6vcA?+lN DZc3~`y~_45.u}ߜER-+nź9:{ߚrN x"rlSI'50s%Xy-M~'G>{2{Rs,yƔ\p})c匽28+ʕݩ~K?- ={P @G/Yv't4K=3%N 3;QgEKǵMr#!joѽ`ZKt{mn>4P>|TNo#JKt}b}E\,hk.P.ЄUU'd 9 xy↯Ha(~%V 4Gk#|Sz&Ef PtoM{FX ZXYWg7=M"M1QV [͛اnԷR67Bx7f\}^[;M 3 qŨ5U"Łxמ$žGTX%<<0٥c: F0 n}U~zlʭT37pa8|1BnS6B;Qk H7ڇ^dH>CdB_TA. ƛ$2kON}8 tѣXLvgz:M=-m]Y3Zy aDq 4n Z"v߲(^ͣ 1Z%Ty(:P -YRo32mr0_9irΑ rkhP!CqF@t强S?xL[zCc-)d;Jx?ۑY.5[`WB!`s\L=kz``}NtQ^رua.VB#|_(ge^6DHs߈p} |9Inb.쵪k뷽;Haʇu`n2p!L 1]2uE12u~"y35Tt?ZrQq$焺22+Yc]s|lЖ3NiOTEWIENDB`admin/assets/img/team-avatar.png000064400000224150150515074560012636 0ustar00PNG  IHDRZPLTE! % %({q1%)O~umxkUNC2) 2B9%&6;+"ÝneM:0o]Zf]}\QR巢w-2-1*&+;2PA=Πýz^SueccX]如kͧr׶ɚVJDخĶAYgJz\`gdz IUSj_lZATu~ULږtOH` o`?&D&Ʒc4Iblmur1{wnpp~`X7TL+ ynI ʋ0Nъi~qy|Yc^㟜}?mh-ut1YTk #H]~3ܿ\UDEAʥ\\I#ؖȧ||usCE51 KM{dQ䭧̙ۢswmkqDFht)A`6ۏYv`io\X8;o4Wh,^;O)}P[hÒvϽ/JoZԏ懅frS3KwtRNS$ܺp`@P_i% IDATxA0AvkpVk#咓E!֋RJ͖eO$v:plmdud@7YǭwR%k89kTM,갮YƏmHYV*QV3gt,K٭k!?j1$8;EVzQw-.EDEDAFa2JjPQvIr4Xކ+>E}N7C?Swgʮ&5wU)؄JoFycYxGRǎ}hp՘dջkj^0ぁu֝m`{j(2`4jw*v:poK4VLraccz{tv5rLNX\Tfi]E15ZvNn|6.K/^$5;eZ\0hEQڂ'`ne.D+>!xrڡՊ%l롸"ׄ]{>df6Pec1I&T]U]`+F >Dt^XU]`]bŢdJǏQ)P]K q3.'*@ Vekjt4-746.2 7ӱXLhj\F} ;ҕ9_rYeI-BM$^xʂRU ,Rkf|6y'׋a(wieq6CjNTN'3@J|w+ 6? ~HQ>(XuLޣb°긄.#ÉV60[EYrBx Sq].vǎ@`ZV˛ynv,Sd36UDD^mxIt@DzFCodyTة9} \}{ wLmxЊQKRVw%ϟ G_ _=2b\װCY K.wH9I:}D }Dkaf X8pDFc@3*b 0Li5 ԅQQl{Hڦf#IR&Iܦby3']( KpEQhp3yԮgμzwf7pT:`J]t*UK dUXb9}.'E V[ί"]<9!09XhհbiXhYǔ !i4x0 zhu~nKFוK 6H|+:pѣd"LJ^Ȩ?t?Dq]ݍD`4tHmJD JkLW0R>ty3Th)T,xW༼=bo|JsQ5jfSm '=yгO( 00x!&` SuJ\GJ xX% \X\*Q;!|.w&g΄q\x̧ب q!3, 8[|>UJ9>P&i.I͆`9W?hi޴|ZbJ.F3q&5tF#=8g0LMGη6fq!|HEf4: _TAc]WH{;6FA@k ׶].A`4 ՎYhYDR׭QZz7XŠ\aGs+/Qs6<`7Q ݓ|ȃ6U'dBz 8ypeQ$(!(hޥ1B3ixc\i#؂mкժ*+> E]C -RB\bקD6јV y1&w0U ~;s79V0 bw[:--8%sO4֌Q"^Z"L_4TL&G10|alllԗ!,#~-Nv X |9eJ! Nrݹ U\ |tI7e#7Rkچ-?[eVj;QQfh 1]8x!CuvCDJGjE$W"3~ꏫ}Lfe(s0Ek޽~r=#)XBW< u=vV/]X{%Eb-^Jn Vدѥ%l~HyRFg&9y0G&+rL$:7_w xPUZ Qkrf,tLįZ:W ܒ?vygg 7py ې /A652ZM&l'$/ d $il,믟(g+II%':EMEF}iY$YvͪbK^ީx;ι/wY9bvJqNU‰g~cߪסVKcq1AZXxfp_>L1˙r2MHsH\8ǒ h4vbAmQ/5ZjM5A$$uz}cc@Ӟ=KPKnutyyNtk5alNwwdCe6tfXܪSg0~sy<\bYgTikk+.7FuXʁMՠU+-71z_r7CX+Y/A$^?؊? dWWqL&ĺ"kkvc֋/X4{huXJAAF/ \AKfQ?Ŗtoj( D`Jz"m')!',( f \5^G&/1-c<[haH%_xᆖLu,q)K"D&K&D2im':V-"B/ADpBe VD솥ۉQvÿJyhI8IYoF9]aF~|t[^m_P3:Q&g%K 0.ѫk牣`k _j:>(S.FkPI_{p_<FJ-bY|Ì`)w$z_ދ JR}~YږsOAudūzyb0 /^oc,|25or iT m;Aöe[$]9JL3dr eR*dr09靛 7jJU2g)֖xmVUmgwHy66 )u>15#8 t+K@7_E|^6D)Ke`q cKC 7dα|E"PҿE\`@ +fTl%9;K]~c 흈fNF%Ђ`*-S)}G.iբ*V]5q^uI 2d* UGdzj+q͈vLV)MD֨t_0CX7.t_B$&3XgWr"/b odžޟ 1|`Nkixz쏦Ţbu#v_> 1 0r%KS'pjf`ه$l` {pO/xK:ǧf{ 9?ETpDJ,ѫHInpL^/5Voe  CnrnKJɕpÒy k&"үF j!|q7r5E΀H" ZHKJg=-l*65o2^ vd>?@G[kTn>02/ 8bR(hչj„ H)Wj܀t {u$XBbJY2Hj*ʺ-yU%6f OM`ݼy-"zAYG/4cH'FEW7uZ,':. bɣXq^1e,o:͗$EIrF ˞]Ձ_H!7e 2Ec ց݃(AG nK-yv'|]yyaaa.PN`i|4;PU~=*&yUTPP#WIgxcK۸J2 l[Z]]~_,I`ֽz&:]Q"p(4?32Jx*tC6=E`:s^\w>z扌Ftيu ǘ+l[Ƃjk5ՈWOi*5gz5T0ը/&8Ώ>6Ļ|TT|͉.'D+T荲Bi`_ww2}s('W`gߓʾ_ɞ{ᬀ)0) 8DD*;5ыj<%7R,| l,rј :O=_h2[C/y,+M@6DQffm0>Pg`~L0sjScCKdcMd{z1@0f`fË޿< _[75%pOL"M&7aԊb_tbG͔đuWBw2;h/0|l Y/+JJ8~6 ×pN.I5R46GRH _3_ 04$Ǻ:+L۫vU"=yדO>}HFXGL*CfP5m~"cpt!iӆMVafUa"+3o0O`W7|΅/#:œ`ťX[H!bI5u9 S/&JiŁI%}Nf@'8\ $ LuPb+B!)Dn&—K̓M_4PBXVS0Ĵy{/ZSG F*C8/]0_LءWܸj|:g-o y}Zz2|M'uFa㏟te<27$ƞecC"'| 5}QH.~-txj:,VUp`x<z_vdi^+3_H4ӷ3VXBr%;x;~KfKRHa,X{o/ٟ(+VQ4& \9ї`H=SXvzD"#̳&T<95Եڼdϰ0|@؁6ee>-1jjHƦ-_.;5Xjjܖ`$֝\5_ͩbUl6aaˍH&=NP%0~TI*6^OBŠ=cQvųk=ħ+HN/[y|+)~_Lb8,јoɢr Ă:-rK*Kit\R|[zl~6:/+jrB_DۃZ; d _`] 6 ds5Hȡ6ͻgnyk?^qnn. ~W2k9t@2N+ Qo]s/BN'zc>ɿ׷"sv_@/H_Bpy(Pف̗|aa{bXY#{Y>]t>f2Y(2]CC^&]3/xi+/62H*Z9K##!rXhyj5 5IWCxqA-ZOv/'㱽~ @_gX B$Z%/KQ->yHʦG&>Z%|xl1XG/H~:lxv!f21/ 6 q&#Ol1zˏl_Q7w mT*85wnz]P[MMU+35rQp7cuteGX o ȢB@IF!D@-*4ԚJ"( KBJΔImbi8q:wι{޽+ua;Ǚ]=J,ۚK(cXɇP|SbAWAnZw.Z+W81tpDv6^ NKEq nzIK}V)  |QKǫRI(\/#F'22 {-<b(&2RScؼUɟQ+rob¯*@܄aO3JV)WlJ9v6oG"7r 3~IT~DdRV7[5'\ mG>1vEdsbsQZ_E(%2`סM!|*|7?kկ3&;;W87מ(I6/ptF#ȳݣON]CI.j?kW:<80<"|KZvWa_O>뎧#L*M㤵zWC ۅ!C/C$VD}TZF1bA&Cי"y݇%xA@Zնm0VxoL64\QIy=-B/omO=ocnkBR4%4$xC' PiU0M7]t3Iܓ3JQ^@7R0ƗKk- x!/4U\9S^B{kdlz4v76V6 ۶-|%91`.UѼM _o]@@Uy 8R_q0 t}wpU61DRPL7adh^)vqU{Rmuu]oײEc/ _}Ɨra;ʨ/ͯJ!'|, 'ÀǺCh';kYmp88J _k{1dL+13q4ldf-qZzi8l^jApj8m"$F7r$v/Puc%Ş|>e';r)ߩ>{_lo2{4`<>G ȏYגz/\ Ίx7- sPUţ)-Ң&'{zzkDԖ؏: ?3Wg_-dA%HwwlBpz ˡ WYD6wԏY>d]k JK,_~& lGs/9S/iƑk-]Ôy7Zٍ|Hɳc nK#=V/edlk^ma( x)_\+׮$u[_K~Jk{i󥕛K}s*V`轣n+W[7z+/VY^/Ko#ޞ}TC/{7/a_v(K:h i|;L} j:Nw2_gЫ x6M>`ܑNћw'&o>Dwܟt7MnuZ~5F| gB % x}k{R|4Z/]_r7%i:6f^PKrG^`ޗ3ɴhɚ&pXaGѹw.zڙJ^lTJh$s1_}266t/L*>vx :&"}`0,zATsjR|,/H!vLՊEv7giMF5))]aeK^tyÇՙ*>ZˎgI^{5 /"JvҪ*GKK)uQhc챟.It2e>Ů^+ed ~>4ZpLL <2~ˈKy.N,~yGHu_Loy:|hzy i >nX^}UjOGDG`_J3uZnٯqb52IF _:q֍7t]biߦrr8+WyOPaO3^ Br+MIĎ-?kO$/a;lc~0bv֞4Vd3ǥt`w8/q^FؕrΎ&SwV%`(Ç935fKŏ/E2R5# ¾1qAV ~j{!Ƕ*`KMgƒ^YY\A9 YR#+ZRJX0yxB$?i~I $r\|O6tL$Fߞ=w:W/`/nk˔2f ( u- ź/`_l׮eꖖ[#%ew::s{iV758Vs$g9T_&5<;~,,7s 8|D}%θC,%A!ĒďpS1Rm9‹ ۱F%4Kn#^.}As[2H:ճzLvCh_z;zγU#2Q *[A:*/Jه x^g |E;N\ןE L?u<_2N..\/إ4u/_~_3u 懻CDJue"w/xYrSq}u^g\QOjG"Yt5=O6iT(D`wJ=ͻB=aOSNYp@4iWe7:,*V\k^z ~%z&I5*|6Z5&R/A0#b_ݔM&ڄ"W." @WtoAtޞA/4_vhޥO9R+ ȊQNpvM9W~GR{A[<u (-,܂ !eWѤ૤EU*._zFQ47_{b h! NzyR`9dR0BrgrrVV2j$㤜,iG6l[̖A-0 fkS2%5\)b/_].-V8"3s_&x45xb3f |٪B*%ZWzuV€zPK"5.[#Ȥbq9B޺//urDy0Iإn_53?چRG>q`u Q%K E ML\˿!vDR$5RѣP ka@2<+Lxko}`JHd9X, }eO Ү|;B]Lф>3VfK % ]r='C/e,>b! \;ݍm૛kz|P86q]ZG5g3T J^0b$$4+ZlFpt%[7kTO 3ܛ ԅC.6Tؼ*`gss?JWKӽäYZeKFFFٖ-((~/6V/1_4~Ն14>0Ьf?SJsVؿzR KSq矄~Z$J|O3&Yߩ c}g(qX*T^H_jF#k=lmWi[Z^^NlEl?/ /4 $#]AAi _Wݺu+WV]jd_f#W1eg|_/S /E/6M1Ƶ@Ki~d\+>%e—2};Wd}Yz/W%=Wo_ׯ\EƝ.+6/Lk+)qy_V \+oSe#y>ѫp|z bH:v28(@+1(H*,;UHn 1CNn$OvA/%U2 s{Xb ֵ%/u>?8s\uɴrDzg/` +|L}YbѨ Ѹ&R쌝w %2c7,f?t܎CCtcNޗKPz`4+ xeǁkz^:@]'OŽOn303Wc4mL:DkzN:18ץ*w/WVW)c;| zqctvKǏdU]}ϝ?M?,x{[vxw~!&ҺύW6[^Vp^W"A #΋R{,+㙞6|u\)y{x5p8Z8$2)VеEϬ_ & XYD,F)j20! ]ۙM-ԟnMGOh*(0|-ReKI'6rEhE /Iڷy&'#;$ [ ^,jr{\:,; (QQ|9rdUL t9/EDvTc~È#IB:㮗GG=W\k{//l ;bxYe@A7R05߿?Jc r!9%BZUF)^+Lh% _$})-_ZZ1YdC%g`B$r n/Ce |ïk͎TNti!_zvId:/X qj}׆ C7)> Kle3͢#/|7nW/o4yezոnyivA/ _iitqƝ_TiE;ܒ:uJޛ rո)y""GBǙ^?bJ0ԊPF\->fE徶ב;r#ӯ/_vK`i6w7Xn>O!B+hV[j#<;,)/xXA*hNqAPlסƢŠKtB.ճpp`?$CQy XA߬|=MtKz׫_|qŠ;m u0I: oaMs-/f(/¥ԞAǜ(D[\7) /yd X$||ߊK&qEzviw9/_=|xVsT,{X_*2`b#gԂkp6LȨ²ڵH z!K%ƗRu89yb%{[auVn4k)%zVEVq2! u},e>L8c;ٵXa(e 66@3>8^TQr"13!7׆z_XFKPZ‚~.8b{"wӊ]l̏P/K+_JD~,UYm4z\i9 fB |!RR}dADJӝ--5/]ŵ--eQu8r9/<_f^\8|Y^K}cG8rwGw8==q%N,&xln#LEOphƂEV'derbW>㯬+)h,صmӥ!LP!CF)"Ov}GSgG;mVOmA޼_VV(kя e.KA.<eH-:xg@c[w*o2sbCdƅ;#b.߂#w:QqF3Z#"g0;Y۷A)5|;842tz~Yؽk~-1-]1Ò=G+|Fo/1X>.$C\||mIO/i— *)+:yI oO*گrm>+.f(-N a<}RS^8հ'ᲀ BbjC)(_'G I 0_-gf☯>_&%5<] i4!Aww(xbKlvXg뾓G6/tp:_H U%rrDEEu|i:k뾂/U2wOen'O +Kbja8.u8R06t`ujoJʣ?)FGR{ϺV.?ik._#qܦKۋ~󏌁/ÑL^=雽w~|\:؝N^ng (bVl\VR-Z [ 3]C2@UU:M#J::+<${oΟ\ͭ2~MܯؑoHgƏ_`bzEKoǗG'u¥~F3U-Úw/r3[nNLØ酌ڹ"e`I1L*B8ENaL3_-|!>!]TŦ3bcw*Kp5[# 8{",Mlj-O1_W[ŧ?7ϑ]M2 0MmI߯ܢ_H .%*`T_'SF޿/EB=ӪW剩4e8JH߷m|Cd eZ*b]~2"ap5ݼ@D0!|ieC;8|Gi/\QcZ>9YޒU~H4v^Agr)x6Wz" ML/"E)l%Ogcvff-ߑǐ/ Ǧ[ _FƂz|ME"[R]wz*{W84Ș k#{z֯ԗoѪ/zOTK=tE?腫|PW߳oLMjko <*q縓yUEZ'hŮZG{_4 uzBVT_F8{29߰$h!+eʢhY%ej0_E LS_jbNtu-rU0 IA/ѷ{tB30쨧$\ vsN/8`fH}n3tq_ۡKmȷN|!FB9;zn أk04z6<^֘>Or~G)]e~u MeQ%WmأRЃ,1רq_; 9|m~D+DŎKM gȬ$TԈۢ S%]K^&3Z0:t`5NyaOLmtX6*`в B|QIܗ[+}- JDZ櫏 SL_,#(lШ:) 'oS W/;~/&q;;ڤ fj:=M;w@Yqbvk]#%.$kKYm[֞_t҉B/9aUmz!rBs\^qzr%oЪ@*1>U$/0&hدKsleSaHI4r$>嗍ch$sh8v6K eTvRN=-Ep/?pPRVIJ_kז-e+_}qH[R_VXXM˰K?_ SS!ROU4衪q 8o `aKpԨN]4,T[}/Tb麈u_sbBdW2Hu;!e[e%&i{ <ƥwU5VV0.p1Y?o%Qhe.EH}\z>m^ /j(9 'R-7_e1p엸n_"_|s$ 2*)LWV֎,i/,:k#sF)(Vk~_W)Qb!WMRƒuU8s%D^|qhjT׷42{{֥V%}hs'Qz_TTYTy}t|(M|}#$T_pV)~5_Ra XLQ')Hg6N M$kk[ypX7of3ycf >>u9";~e 3cl~Y_l_(} c(d_ze[DǠ_Sg̵ ^e|'m;k˲jmE̶*.J@ ]Q.%.ѣN>#_*b~=U1iLھ|Ihxa|ߚس#+*wܗ2ur0dܨ(_TaZc`Ď$H~BC^-XqK Ǚuڗ~o%3bgBj>knb p+ܑ.-'zlbU.N4KE(YEo/@خAv,57z2_MKq%VBO?گn5qtKip_A:0/A(L0 Ǹ8ל%i-KG_;ќr4[W8r@5U[w,q gCd5y!t³}{&+֞D]W~ z)N&˴7z|9z.݅Zr`x#,.د+8HRjK~2IIY$w$!1_3G0_1!Gv 75py7Kd4ΐi%EF"_knV,Zz4 IvqZ3|T_+r_,dCg.mªvwYhe1L\eeC\1 LrFP-"%@DyYPFI h*vb3u^^'ïYImG$W_|+S!- %DKZ_T9nQ#_|{B _PXJG%8o}nv:\+ sUq$i.>0w/q^@{5;,Dfao>o׬:U[By $,.`3j%' ;)6~|ēG%# |55(|!ЅH_@/dW PK_;bCr:퓩:`Dwy)~cCNwm_5c#/2#ޙcUrn*ů<^FG$x<݅j[u94!n:k e].LdqlP+eՓ;%cW⊪p, 0_+6 7Mf)|57O/rlȇ^L|4Kr_518 d)i`A,zecM/ WeN. JZkFdNpYH3\DVLIF[ (l|!{nxET _. @A4ARbVҾd#qs=e`⣁ŖeImy2B *__(u+CZUzQMDn!˪x]G烇ď4tlPSIU^^T{ -I#M acl=&SZ=^Bb( Hf΢һ767~$xWv~s5'{&{+ϣDf/zNG%ao+ʈYˢ1_"/ F`qa^doj-_帯\ SkN isy>)$oߍ{+N_В Hk#)d{aL 2%==ӂus/= Xh6LE.2:G̟7م[Zvh ]zA}I~z:?C;ɨBQ^u_EO4ŀuy ]IKhz{Fcc]>9k/9ue-==SSA`eqmV鰂G}Ͱp1{ZU\dmUW貘*aAmFEFmF!am貴@7/lYy"02}Kj!S|[N9.=w@B7P}w_x) 4)YXi!дȤo|j206R2ի?ȥ mbH;q)f/[K,_3R,|iY ^Tqlٯ/%_gCޣ{^^xc)e襴~)|%y6ҖMUK/Vs76E*&-0RVkrܑ=mگ[|emtSB|9B[ dמMn| 8j F.aŇW )|}Nu*syt~ƗzP&-|mkyASEhq 1+*ZE/?\ Z:oG=Wqٽ͝!Ikď/4:00ڶ=ㅞdg6?e2~)qjԤ_!-OPF;{6f}gR0YuOp=|Ru_wʯ=H}hjmmr&6ON0i$^΋p_-wвt j PqEgIMKl,u`H 15|-di&v.iˇ'F7@0T[A9Y}ZvFZ]7]J뺙C/'m3T^WfHJOb-E6Ö)ŰVEaiŇYd#w N5X1_^!^DWFVKIT`3a)Kժ 0#BK_̢_FְA81e'9tCO4f'K^R.qrDסyg _{.MHC)pRz%܂`-\.IRoxpU:4zsHp5?S7A/h%-@ZLb$C+ݸrcEo;t1K1N,\,uw/-L\KʴPZWV}z6UT~)R9zJh%C+vWk#itGpi?sv*C9"gIS51HD/h}# :{a?`oA t-eXT$śmu4~b%x.|52ѥ)տ;FX%$I_3+w& ze@kՃе81q H8}E'f=5`ꨯEy RU1qg[Zj+tY!BbW)_?}Vkh14bP_/X}!Ne3oklpF-([+/8 D-T/.+xݣc n p[W߭S_}:'Kz䀼3%:BIwg#Zj)YѣIPRRTdos^;}X7AkIfR"ldL|+`e2ދ`|%QNC*3.YDTbʖ6hdEڻw3{#X8),`8( )z^R<M.;o%Z.v#|A"s yE^2|FlׇwzGuCr=M Გ68YElZJ|q_j6<;z$5?[E _?q Ib.]*zt.|%ɥ%Kjt`j.>:|sL3ջ^au<:҂\/+i|]ꖋ<]^|zumF$7UU 2|Td57{"HL09s|jS+74{zKL\i$lI\ƂY6J @o?.joCz/N n;?ݒGgQ+ 7q˼]*ȭi@Ko~>MSpM"y-{e:sDn"h`rQLD-$Ă*SHN!eMffdtَv< ˏ}y_ t &Q)|^;޽uQɓǨLU^\e<jogł~Dhf[@`̯'<MEh@Cܼa/Ε*XnEKk&fzRdϫ/Z[7ufn#QޙɘAL L 2к/۳ bs@w6V%.Y{_ݴ]758[0pb A/%BGKW/W?fHՇvQ:5bW ȪUgOa_bu :;6 27 }/7%12'ϺAٱ :z/ߓ|I L;_85qFL+fVAЇU0+}0_x.ٝ;TG!eMfR-<&w^qϝ=:tu>[BO6\o;jSW/>i4+$b+_0$׽o _YEM`FobO*%^_o!&<`S+xc}d!u|#2n|!J/)l+a "!/xM߹s˪ҪU UHN.K}ɩ ˙ g$%QLvizv5^ E+O~z|oؑV:§cCȂ|2 HIbXcڼm53kv?Ñ?zVzS_cz(:wcfJ×+)_\9Cx~$gD%Œ8?eWR\\e$+k;z>U8ޮ޽u-vIDc?čq((LI+` v `Def}nԢ~^E4ugϹ$cJ/ٛ-5Z+_Y1[]VD#%.Ly:ru_qWsė91(@kT`tuƢ͛paFP6ɅgaufW:c=H9e~_ܗ~+:-ǭf|C2 nzQ1֒Gد5^vݳ^eMyeeLNkG,2.5k'\)GZ-q%{%~3($0{g/f1$wĻ_D'4 kگ5+vI|3+}O"߱H7EhM~Nd"! afK/W[w15D]N:`ƁjӴ쟐&E?)9śU?ò\q Fz>rcx๟Gu/\̨Uql vBKjݶG Vh<^W<(k6߹.M~WAO;>Whn??~ZJ(_ rA'_ 'x巎<%Jd&U[ä7]g`,>Sy:W: `)*M1\.)k/q(`9rOf4{Hvwԏ4$;jDjڢxE z?1ԟ $dKF)< @.&70`GYg@HCCXAlJ𡼈>_૬4SE#-t zjGwJV/CQ=@”Υ|q5_Vګ&WN~ BgP4ojOfXZ z9xqq< _ /6u\x๳<} YF$R=d F* JЉkJW`ӌFahWﱓ7<|~ub>Ji%7%:|z>.|5"bG3MzvM qxŠZ nH^y\I].wvG+i*"yb\Q%̜[t'Vɚ?,WˈI%NI-) ]PɻNgsff{trVhSaoݳ|)C֒1 ~_ׂ}',46;9w?ai #.xo'cZs׆<5/&m>FKo-3Ȗ^k_bcQ'e> e USW,'f㨑o?#|qHPyW/ꇴ_ /N8)W :r-H)p՟"0K倐A)X}G !TLJT—$T:-2bE@" =tZMn7/$}>9,IK1xQG{n!WTU&\4*_[q#JO:ҹMٴn&5[=Wʩ]<|99&'G D_`6d<(,/t?~dnY|t_X;|$ b844B9ji_&zȬ#4ww+XzӍUd/55'ԃ/_UQu _<ݟ{A?ZڔRhU:cd$uI Syڡvn &f h%ji툏'v6B]-yޥTc֜$|%&&3f%eL6Rqhu枻NWn6g`S+PilYg0euD35O,YtIoG"hUI}7uNV_~Y 6&2m)/R8:bpVl֛Df:noo߿&):!w?_o7L;;|G7enjQkRH|:`;tP}5m& {FSVO?+ _l3Di:J(2WDaYBK $r+ eB^29&2ujucbb o9wË(ҝDkR/}Oa7i_DӟMs7[x/ӹM^DHGs/ɋ/]TW×I|9`07vU_OүY}Z/ij}1pu}Cd;u1v _˕fvYe4g 6?peuhk徎}iB3ZSWY1jJ#b+rk&f?NPvbvPJAݮRBV3/6mrHB踗է?ls+W^5 ?[5Zfk$Ty0X|irc/%]>Zq̾G]aXoB}cg5j]O&E\? rc_;r}Q(]JJ W&\K}Bzs s jqS- H%'ed4*/ nkr$k Ua_7#XO7|9"xU"/!THA ey2ckT ExyfN`chp^z^sC5|msS3_z1G/Y H _<1yΡKyܱZ_`σ_et&tVfeg$-j). CHZyz eRSxW]S"#co_C*jGw1Q^ʮ5Z8aʲe5Gz|_܈_O!ƴ,1ꬁJkq[Z-8hӦTL6+5L`HD*,WTu`)~ɔJ+%`1%_Ma=C"%g%@W+%6t|q_K(άMnZp>:xlNT?*f[ U)T,%4_#p;חv_DcnǮt}h|oPo@s4BccEE\NEeNY|φ#1Ee~K4٬ŋa31C{%~άNN;/|Mr|6/*Vʿ*_Ja5 QIqsL$e_S_v[Zx>mkr!d]!K_8+ _^6|zcGsw=GK)eg}򳯟xgd\8A%@ĽS.}^&fGtSɫ#]-W.(!~UBl27 XC#U|O~_2d煔8.Ux{yԒ B3{8&/.-xqjI/<4g,} ֎n/}a@sNeen$Uo*:N8\ӽXHhfdL~̛Vj'^eߐn<`{{x3cFir:j%/_4P _Dzo`/(OJ6$z]5J)+$pJf⚆Čɯ//Ɓ%uev=# &%d-O_/K ך$DN+(,(pcW4hͰVb@RJO2I.`MfNk L0%{/~‘8|TnsҌ[kktC 4eIIuMU P 6PK}L_E6~83K_hOhվ:ZhK\(|!g+FBadH2$LI0嫿G^Kbן%oېy[5@ʻ+DWj3}K}YGI'>>pV/d /\~sG_dœ؃_&e0drI6{>(__ mċG.>in/S7Tֺ;cFھ_cly$ã*2%_ |)hzeB("` Iku)Z|1N ~V򧪾_)|^kAb~o!vфYTGD&򪤄0jʈgSKTޤRHd&&fQG+R2vS9AhТL//BSRY2xJ$'PX;Q1bsKx .Wm&.HoAq IL-z }#rP&\~ %|9DwD_֕k6;IMڵgt?"%|-* JjĪ!Jm֜fr_BdUleOBG{!@ZJǓz1 仞)#d39R(z l^piّ9^Hfޢr(Mg"/.|yݗڶUo^r-Ki_H/BsӃ](ǫ=◓FRv!Q8~_]~/rEK }ֹ/k5gډejiW _8XnldpVHr_Z;_|E=|;4|=t}߰:;7׹W֫W39caHVAEnfIٵ C&U6`̸)DKZM2UDoQE=Ŵ)/E_p⩓vt@^}!"M%LX/ylgD-׊Ֆdɬ76 ϴ8!6C |5GGs?'0P1Mrˉ>d3'>lVڒi ФYzf0:jERlg;ٝD2՞fWS[FW -kS[=>A%g_%5n,# T|mѦo9~poۺul}d yF52"%y_a) o߮]lj,rVJR[^wֱe_#)ƍUh5~Ͷ^$ "isǁl _쇊I 2)Gᙁ̹W/]'VN xs_9YTUi)cZa<' p_/JW*t"8-aPGP}B/"ua~_U/UҘ:eNR× ڱ|R}-jI[e侻su(k_c. }Jo_0`uˁW OyeӾ-\~ʊNa`/e 8sĔo-h|1}5P|t0uO-*Of13Z=QO js#ޟxB1;_̥f4E͍5#$\|1YIo)zZI B%FG(aPG_l6C.esx|ҙYWc3xEǔ-u%$v†0ľA/&שxyHԕ/IE~Gu3gg7K*ح 9f:?Uq$o\M_qqk{*e4>XJKkRCqyZh;YQ/6{αZ}[ܺGo _e}pIqay1Z,|_UC~,Cr= 5a{& ߗMUj+4/k-V:ROK uʃXutUP5 ~e9a1\3TzFiDbH&?>=l9u%nj: CC-]#WEZ%+0)ZzagltK՜|.+ >b[/>g>c(caZ^NגR75Zh> ʬk 7'iL#jʣԋ07-㬑WS֭[c*oLneVGzƒk%Y/nЇSՒ*z葽 Fq7_yk`c R__t)|_ef>Sc#W?$`ue|YmVV5X}(eB]K4V&-Z)8v4=VƗ2~;oRnwz @(žby4 UIJ*O(hAä́د,Tv 0$|I84=Rpdw2u,c`Dde\ -^/!n2tx9S3دYjhf_='zISCM*'{;r5ҵ2fy%z٪|F]뛌(C:-H@rq DT,{/ 73,Hɴ/m^41/$|]?SS,͞!QK ܉VTӽ ƂGװΜGс QY0.=Md,Gqnf+ǝ]h8t_7rHEȟ>GU_o:"`WܺD'A_|a<#.3cFs`)hynuA_tVŦ /I2|`+-.'9 q^T+ЃK?xlұׅ!jHB`f"GɈw3v>Z`˲u_wˋ.7_)3Qn0GxI箩S25A*.3gK`^|/'J/ #x4(^L.DfH&|Bb7haL’ض~_/t[q *CsVpWXi_IEE?[#u;AqJ MmxeOyQA#ڦOM29ܐ@r#yR=S0AסC3,z|=זQz~;˹U?ϳk/ [}I!X)kf/QKȁr EPE lz(!6Zx@m?kٟ 3DzaV)/_-%#o3(5yޟ;/g|Μs7rzmnBz1+h,[L:ܕːj2 c_ >N1EZXVswMrC/{4~_E,Z21Cmig^i Ka$[ajG殎߽mxK/nꈐY͘fޝ?cK>mQt k'%{1tj{[$3d%\WW_60 u e"᫪&FĚOmeMt@ պ/T_^x~)IK /LPu/oke`$hR'wԯ|W7&_ |Y~KΞ~LΟ,xĐ䮮^H7/8|Jul W rE19MM$A^@ _%u!-3:4EjFސdG4Α[M'7ɤd1Oou^}W?W|^, 엾=J6. |!:R_cU5[We`!%gpk X//~mP0܉swGL H"!DD@J 1L\E//.ͺ]5YP`& C@WY1‰JpGO;0K}qu$0MΜ_q[/R/`g?YueԚ}iKl]aqQr𥼯ŗ١nGpEZ΅_{!3a:? l.AN?{_/+ҩukk'cm ^XRM8mp08Yr_+8,/ކ7=z;iI c4B"@$G~I⁁DYK4(hn.t}렗`x cfLha,sP,h|MTc&=qvvO|MM&3.+ɟi F _E^h$wرs|LS{WRfPz pSqՓC"춀>ִOEPG cG=eDhu]\4}1HbXET.EwVK:;|~sTЧp$(\^N:@jg׫LZ /]CfI/i?|3uȂ3OZz7|7OliIj#LaH_eZϳk{Ӵ}ы+b|զ_/n-c:]94$ ̞&|E9|/IG:WO@* '& Bp=);o1_rNaޡPAaz 1~f^+ʿ&sߟ~!T0ǵ(c{B+{:5v>B^[wx8BeD` # t|յTv#PRzY:g9to]=oi+dLJ췠"Z<]K` ]+K+ B/-.OǕ v}Q*S/]ZI}ODZ2yH}R$66!8FW5JQ/ANYoV} ZiG*|4l[/iZ,4q㲼Bk]l '| o]c;b8oGGLQq7Dhyt#8j_+=U|}=i?V=u%S>I{Tu,ŅOX|հQq67euzUʊye6 PQZ(x܍+D-=5甕rب{Ԛ.nv{ӓ}DAt4%K+x/czh7&ŷen\a}A B:XΌcIfhx +d_ĞK} zg*uff$!—IleUf,1 {wge3 ,dL䨰Hf}}tH`&KK 0q ~zS|܌R*=&(xLXgc@׹s{UD?dW+wVh58*^P8EBUf2vO^K Q^=>o"VPL'~A8jB钰ev_O`xe+TXzy-0O/Ǝ,@5t$ J/[ЂMEJŨ ~qcI&_ŋUԩ;%IH2eW%~enByp^|9b㽰^̼Jr2.Q':JW3 7B=0rT43<&UEVr^qL݀q_mݯa>KόKgsklIKKWCSm#bɑӁ*3<}ͳfç~Kas@o]AA`(?q,X6քFHơ*WT,<֫Q 0GR).E[b3^._畒Oic"2ao䥽&<*,)1Eu5G]MD$V~3G=nY4HƿL5%]nPv"=K~~/ |QCReB-+ Ǯ,.f]HW5Qw渼Wɒ?˂RրuVfFpGۅL%wDQI|`eWA E0l>opPJ$y'xSQ%ز\?$0ꓗJj_q㊧a~[W^j6ע&NHA_H6Cz:FE7 ۞V2ލEWH4Հ颖GYz1`uu;9"60K#Wǧd-i3BPK.#!op kW^xiRgE1;fjJ+_kK+/dY,/WK̽tR!) >crb[:.Iɓ"H7sX`ըډ$Xs{^BN'%rfZm(i?ꓐr3Zd3bGtODLWZ|qIH{Ϲcטd{FowuԨpvCoǷ%LX.|}·k?t!q/|1Y6w/f9~Imr+}巎\WgIp߅GJAD@*q_;Z$c$%ٲe-[vjh%*S6Rj)s϶ݸ~q*QxA ONSY.ù63>q ϝٽm7^'YSA4 B^9m݁A :9ܒ pF|Xz 6>Myj?hirnSڱ_ZyF;I)_&'W}]}CTg8x}z>e32q R-_+ 3#};%⮖զ^h(6JcT8 |4c9q_Wn>2'f毪rBnF(K_#[І\!|KR}Hc}/!a_;xkiJ(|Vk6!c!Jo/ܱH |F¬34;wˉo~0€'5oSYu@6Eog*lwƍ o0捉]0*#*[|?3ndN7͟yhdfԃ W#7oU/ں3cR35@ ♗jY7`:x{뷭jft{>|$]T6@/`IeyW",(޺Mm~/NN Gٮ-̺yļ^Hthe:وʳX{kz#{$ u)bvxԜ:/wX( T1SWL%}/_Dzp+}`O? tm+HCG۱* F0#z]d\hd30KK|"|-w,##2ѣI5m!KW_r fSh_VDeZR~_n+'N8ԅ'#gv.G. &7#ef;>237i/!+ Ťa/f1lOX^_aAA$ܤf#+O#t2ŋ6-dp@}EY{! ]O{LBT5Q1Cv_Ü{r_>5xӬ͂QTg5b6EjESE>8DE]!U _kE/`|C:ܙc|uqfZGW>b,1—>CՋ/4 _.v's?{o?_(Px5h;|jM􆘡q!_}Ľs_n Θn z휳jժ{ -e}^_.[ /MϜn V#T4zҼ ɕJzm句~~m;h-K/rH_KW_|+_}:r[~s-%_u/.\p3'N_ qc\8)h_3U߳m 1 #UYgƝD^>e%xIjAiTjn&BߞDbѬ Bl0FlKS޺wۮ/@62:Ǚ|kK{pEMZFXOص8<`QQ"nK[PyDU&/`x/ŋ}QM'UNMҁ|ƲF%-[JhbFD6EVdń{п iLqm%C}gyدfTKLE7/<*WT _Go8du2{07Hs~N=Zz;&&"C(zx+crr.WWGCNƨ贍w3=rȑGY~coo8e4v.e꫓ ca \f/?)GrNZ]kB?"VI<'U9K}M5u(]&e_??i;q_NsC/.>ɜk*陛 WWQ7hKl9R=&Ff$,x\N/ VM4T%Ɂ25A^ƊN`,nӗ^pR߾}V=B>  0n5H3zʾmtHPθ/yhr#[0 n"ı_Gwr^Lk(B(L ͢g[.&IvU9[[6/ ~MPuQgŅw w7=>]\:-;nSQY6;^j|Qy9GMS2a };ab'"6;eǶ37./uEzR_[|`s\增w.?x7nǿ޶ 4*h^6XHwW8$MDũg`TOh!Jkr"SS6'hJE ]DRbc_fFMA"F=n=yÓ'[l{zՖ׌ɻS6q:Z4a2tNB{!vt|k[ʲ^9JY m,^xeXTÉji\^ytJx r )K!!Bnد5 :t}i236/m$WWѽo0grj[ggĐIě_0T:l3k33sgnmC@M{Ko3-SeT^ z5552 /^)mQ0my+C74n̗wwZ02 E ~J OvAыHNz/69MK T,a z뾞ɦvR8L["]Qkj!?lu _טѩ/Dly3X1}C͘/w@ϰ0//i8wX~oi-W_D!>{[$!$gBC/ 0=>t(j鲑.t+a{~e/Q>n]/)%9 Ir_Go,.=rŎWKE =+_6@ؐ5+w+ cG4FZ6"c^/XD_f(Wk=+Hcs_Ni9.sIf1'w $Qr7k UbWe+x|QOk J_zk{t?W31ˤꆽWH%|A=F+pݱ`#"ǥo~A~˖ Xmo_Z5w c]Wk;_W| |ĸ~ͳ5nlƃWϜ|'xi,) ^R.疳$Mo0$ѐz z>?X=dp)^|ـ~>:Z$|ue'R-W=Ea}qJ _tlЈNG=K=ILn+|m9$5'_ڃS/}/|>+|b1]kѶ$z1w^&)7Ĭo꯾fVܗew+yφf R\bW ?+ {߻Ǝ3g>:t?} JygFOaè˛RfFkb/)h0h}\B_{9|9 ;| x)^T ~Oz9|i dNr_abW)ug^k܃cV{2Sx=3i2<17kOdΟp`D>̄/FҊZfK9m2Tzm&{ ddi.Q."!<*/td7u?FU$2Wa~i}5<~R!z-2&zQcu__ +/j^ܹ_m`Qr56EQ|^=li߿ˁZzUJx>a9$_Kݙ/zs`ђr*/r_c5hv|J]Fc2/4|f;?Ushwp9, r<34_ޞm5 ~aRܰG/HpiRz>=ܓHN`&挀_kȉ;kKEwʑFK]ڪͨ0D̗!q_4D}s:A_oI69O>O86|H_T BbOΞ2~ʖ ~?pƍm@r"ӧ;x@}O?@+eH LP\}\=}g##SCoۆ:Cܩ1h>_Vv2]=jڡ!1:.&ꣷ\8+pȮu/-,W&8}\M`}tnIo-1i;=MCLʩB—^; tyU=qnbG 8aaHxľ S /Ҏg;~)bV2J?/xӭCd0^=Fy]ŊdUۦhάX)TiпpF53h |)ztS>_gBn=+*_fGB=iG-Lɷ}ey_rUH{M0-ӖduTqKᾢ} R8NT^3&5/+0/ WMF#r?p2i!==Z~yE(+6%.fm0"\/fN/qK:va*ͩ#)> ]kW~?vs':,,hN c6q?],eK-M UvU(x˛H.z nť _2wfWc6u7O__V-c`@vONw.Ν춝&7:˽D}._~W{bo>@ r~foPɓ7;~wj+2c 8΂^ U(G'2#5,Q5 w)F/g?A{Fc]|Yj\KCGcDfyG/S-}$H{9z9 _U~8eN9/U- h+*QX^EKz5Kp*Euũ%كsы(qrQTD{ulJ5=`g(T x _K% Octܗ^Gn^8_ 4Hp*Z$פa|Ej+C*KJ7F>+Ww9JcXō޿ԝ| Kt 5J)J ^$RWc#R y\2mQ=2r2kN` G#syьxgˋ/U7sZiEǰ*ŧw5ԮHF ^<7,}q8yhrqhGGH)L KKt^%3gՖm/[N\δ_gܝ|7w5 9!7—'Z S ~wT2rFYelDnxw/Ԝ1= ԯ9f%U/'[_~9|)Jt^^I[\WO-5zX"Gkrųp&k#LCJ@6=;  Ѥingjk+.k!xqLɽ3_))#if6.v,Yp[9.)z׿u% _|GWs^Cr %ŷ ~ۃKvUz9|#!)ǎ%v2fE#_,J{ܤQ)|mj"ȕړ!e|S7Tfa|0N)"vj"F/5\*|W.<[8uKܫ"^Ԓ3L/376 ->}Y\H/t?jU}aF7 q=y౬\/zW9!xAO/8#Qoڎk<xM5~Rk޵_kS:¬r҃WM|c1.V`Gȗ[_I+ ϘhCԲ^IBd(S%?~y^ŗ{|b=osѸ/Jb6Gsmo WMH_({l7#J+]="'o͗TWd*Zm%;\5)3b&vtrQO V-2^|&28]lxJjy4;6u7^1:5yA"x _ @3A噾3-LiD#o4I}g\&GN&43sJ}}Osصwm>!_ˣ-d(jtef7?ZUmUT߂z |qqg\,V] _s7i_V/r|Q.rˣ<}Ew`ėG&,jΑHy͗hx A,?kxǸIR E|  D.#O˕Җm/F\_Xg^|.S4nDčwoRȵCkӿʠ{f=vLwd*O5 Hb` 'd͂oFŶ?duo_$J1{?_/j7¬^"FLF 97R9"܋M/Gg=̗%GA㗉y/j't{_.$ELlKK̗ J͂~&]tXzR.彸,tuה'D/%iHΛgw)g,cv}U0+_"U&|msre/iξ_9e0B,KEo?z̭uI{u _DOTLz:ֵQLw)'ۭ=Z^׸Rc6צ+VSt"2g$0ir9+o^=C"K^|yGKڤEK~K $ғc;r^^~4,zdS1դ%—_Ң}-aQgakF`#=#,-8&^:AgT*e ^ }/ޤ 6JH1K:l6*$+q ǎZ{˫ž}pmv _&e-ՐA&_th/)l1`76FkG/xdk۶sWqt{%KJcB3 +wO-p\r,R-FtIJJ㾆'wW'զgkZ_Wik$CmI0[)OɪЕ!vt}?k9)EgE0ٯGo\]Foi'H=ĉO<~sW@4|us[>  g"Us^?u3}|^W6^}0Sg.e|O f}^ʌ#ubUJ[c=*Zf >@t*:G'E<3&@ ͻ!hhi!؄M)X@(HLZii5m$Pb&_CZCdhPQCtTpWaR0߽w@%ιx/cjV /جy m|/įodz| }rTk= aM[!t?V"of^=ct9jgYSmm[JIY H/'q(_ :ezn[mt# 6_WCr4KR2`O8Wm|y1,%O8j6X|&n*w((V//v[JƇ$uڼ] D/nB5K-P/9J_h _×MWumzA7^KqtVUd_Uu~8tDraaz>ro5h X {Ca:C4QsŶsNنjۉD/JP6jjX$L+_Nd+fOIJ/`/Ν@U_+gg }G8+_0N,՚Un1/~݌JH^ >6f٥+޿3@Yp~/IzLȰjojmMl=v%}!5n2ߪw\+}*NHVA=If{C:Erů#La~_clb壸\GOk~^+)V͎/^gE_J#5kiԪkq%oTZ~ t+v\w]J6 X!_U-D2 cm@ SoFb9؏̼gg9Q9yU\/|9~m`U5gbe5<0hry?*3'/W"~ hEu{oQ:!|*DtކV"&N@/^|B7M5Z嗀"A"{~G|O^kKOSuxK!/᫱?uVkȻ/ ?v׉^yi{mK4(eHmhG{yת_EG!Tx+OR ǁ5qc_=T+yuɱ;NT/O_\ml׭kŸ>~̜3($&{Yz!O/I_e"Ct{%o{574w h|qPM#CW{C#c^+]ۯ_1_`HRAz5CbmzkyH{KTf:̝0k޿B=C/R{gqǞ{Xlkjw޶m&u#/wc2B|O[}{^V[x 㼸%SK_f:sѩtvy-!u /7d+_aPIG}(_n}Q_G}JX`KPD/m BB|B8t&j>1$j"HaR#^/+/WrkbA&۬|B}ƥ3:N~U;߀//!rRZB5ڤ&'~)wXߥ]} P"wx%a.ɜֶsLG@ШI`u/wJ5_cdf{H9TX}^4lx^EYK|eUh\bq˞S3^H("S(`WQWHt2Zŗ](/ǷX9!Kƺ/D,oÐUYpLFG| ޷ٿ !rLLX.ާPASꢼnVOh oE cUH঴"JaO& jj"}C_ =]Vm,%B/ӿ:/ vMǻ=*LG렸Չ|do:yRX=EsBs#V*¿Y9 7^nI_Ufpk5 J įNJ{z$$*-Ë_x{Hz-[* $5^<1P~ Umbtb^;j/z%f V󁕀ź/_jR QH c婧~,p7N8]b7Dgh'Wڐ3JRo7?CO̙|3mb[5pbL Y~|=U^:NY_N_Xd/SG_cJjڽX_ w_V +S~T&LgFHܘ _]R£?(9%|w{J 镌Xp__~јfbH~%D-։RR~+^4-kO~bq51*Fbj$(˭8G>7Ym(k=ϟp3u/nqRmkR]rLŗƞpxe4罐9P%OcR/vG/`JjJ/A-D>"~i&]c9#ë}q1/UxbWW,;챷\eG5&y&>EޓK0P{R_MU;O34R/}|qnOtI7iH猀&uڻqN@[kR62NX )>"q4e[۷ˁi:C6n$de_.unt^0_miT?]!9~itPqf!g}w_P0z;g^ccw7uc"JjWW ':˦ z|/^|=eE@ѶXK k4KG>XU .AϏ&']R%]*0``j.Pu1g:c̙AGx N>ÿwgk'kni(g-#^ouNUʖM)4hS5C57_׎jm{t%_%z6 _-]'/e^%hؾڗ4iބD 1f۹$쫗w0t 0%'S|ixgEn\Ŝ_IN :Cc}ov%22$'eW^ˮ=uR|JZkc?|Jį.Oj؎I%"@Z) qV?{bw̠ vx_5_ݘ5\WUOaWe))sҝٲ* R˦#j{o‡7Rª8PKfX2+in3E:ot?rfƍt?fۃx6yjuKЊ҉Kc3KO|i3C)W}ƅWUτ/Ў=[]wcLn;"H yJ8|L6$DI1k2Hmz&}-vTL;]UzѼʰhe8RZV[ _KQw Gu~=Y?}+("+nrK "eh_y"o_/ bfh rSrTZ z1l?T[/M_eWդ." Pˮ,T/٣@m]X_T(pЉD]=AE7N,SX"XPV^JRˡj\WNwQqx׿[\W_ 8.|ѫ<9s3qC.\g^}xkU eoξ|Jܢg%G/du;󎞮Sҋ=<጗4ԺlO!Rڋ2zI>uӜ3e_ɓT؃ L>z{!@.|=/Sl N"OM{Oc_|؜m%r_ Vj/R>|2/eN{6V_jx'j5vˏc֩{hzLʙ735S .A~! _/yf+`Q9Pxp7R(w UkTJK9v]́ц^i$O,[ǾX~~yI=|^_x/zWp?1c64!ŋٶbg{P[TbquFc.!)jU2%滪k[2l!qy.'P^>y}RoR([0]"_kYyqίs}0*:ٞ{AkK 4 b%WĒQ/' 4lM *aV6zzkP^6y!y/amuT_~LAd]ыg|0%G%mT,u]C3ݸ%%X,5{˽K݄K{阛/29/|ierh ѝ,l`2Ǥq-D$|..Tߟ .H :"d¨ȗ8D;H z#/P+ŗnmӽņ/3'SsS 9t/`W^WۂcպTx&Gԏ/t13? [eȴ2HFvX B":;krjl W^tUpS=Bc+uV_x-OKIxU_99|pa.+{˜`c:z8Z2hH-B,g2hmlkYźn.qt69{dKs _Ia N7Ț/E_O\|,WGI?릐X ҍt/J2rNs\cE^Hf׹B.oX__" ?spl5N] ^vEM`D%|M2Cw70sģrp Z͟4;,.z-^į4k2Sy) :#m,['C/NkemtIX,/a/%Ew:~ "{pt?K{:Ў&vX_ u_Z|Ť_~|LԨbQX8Z~tZDӋ`^˟G:;H%+ɎV́ԧ]]U[ku21_{8fyKZ/+IU$|_w@'RhmSHVņ",㺴kW%cEv71{X`ITJjp/F]i~5UsZIIJп>pvu4lZSҴQ2|Q<{rp/~qNgv]祟=f)&KasPqK޾B'>B#KdGZ/$UtBp/S?Nhv9ZuC#:I=݈_Nx5AkP{akX/upCߜEQ"{ҫzGh#Ư\lbB lŋ_%#Z[[x0]L\*5K/,)h_xoPRi.>S+F4 Z|٧,r2b8UF^^,i˩qABk*atNȘ}CN /IBXb!᫩qŅJk^L]M23˛aִq5Oź#3qC%p=ÕZ^J/+=lb᳧_~ïs~gW{EP˹`e<' ^^h{k#z5=#ڗj zy'E]qɹdS<.9Pt2#?>0_}<6b-^8xjlA^ܗlҵG'ӵM< ҪzG++ _c B$﵌wԇh;$=R:ckBeŢ-LK $se<:ֵ\^fo0Ծ *H$bȤ?uȢh7O ~ŲNGFո|4_/a͎YRj/^(^#`w )a䀡U=ʉѝ א|if,H}D_/7ůΑc_`[#вjp_=|e㗚ecZ+^Shz>Yx:϶[տbcT{ם=pa M{zeߡL^3_Hw<Ǟx:<9*+ʰ|{2zX^/3rgj_JQFJz-#{UIFO;̾=Cww+tl' L/u jmG/%%^#j>g/Y3 |5ⷐ=hF J^&aj\,G1}I_=7["̎ɟ3!pkrBibݍr`]f//%?Uͬsmz:DAM% xb*!NR𥹅o0g[1ߺZ~t^Pr%{L X/?.^w~Xq3{v?~hX"z!͟`x-=EX.uC22vu]"k a!xTZB&_$n a 4{X8b%|ZQ^ `z[bJL-0)⹱_x=ؼ?C}ZJ.ȗ&|M3EC$ՑK*f=q"6.:`!K7wb|P=CEvjEb](|e^UT8B71iG4L^^G7Y|ybꩰ`7!h:;幱V,0pi5/%¯?/~NbX}UQ_!mHJ ǖNDkؔؐfV/\~y}X}~_-[V!-D/m^TT;?Ǐ}h;!8Q/¯;ְWvuMjBgL1G_V6>,gv|4/5N.F_}9Er&e F_lW`&+&~~=Nod_3-<f\55hbm^D6%|=:3FOL,rUhȱnĪ,_(I7_:"3sj\ /}mLS,2S_W'5SLD*uTL9Xm+X: D4Y qc| Ǻ~ewO?-[wvk_+Ɗ+w~ ~+ٱ\{ `?"iiS$À|)fcgW[$r~|ɀ;xq|%,?)e.#^sxp=k,Ǭ^2X9el8d҂RGmݑ){t"Xω>;m3g̛1&O.]V:qKk@Sٯ855p/$],&~_p;_2ǻY_r/ ,h9 P ExǤ(ŗt|ZQ cįͺjf  No]ڭ}-: `~ HCsK>bC4h6zFE"u\D)<:paՀzhz8a'V{/:|vayRu&<ޣ?{zDg[+CGKwC E[rU{9Sjm,-J_|/ew4厴}FuSsʣ@E2:x/ݣ|\({/3KeoɅ2(7 fEKkŬZ쌹3crߟ=g0*2mb1--q&=V+_R_]D׍:V/uh ;{žځ5oǦC:Ռ zەbmN9BE5}eģv Irhfj`t/g^G:+%eq`̍gkTM:Xu_h`Աrczr>?J^+tfo5z{=qPWXb DKc灴Kz'+ {g~;+ǚ N$5Vkx0"f[V*V>0ܖU,Qb*guQXQU62Ǿ*nx%zGP5z3 Sv+N笘81WiVj9:Wl߽-~&7ϫI|ii]ZcTӲ+z0A r_ fV6ٴKd!յde7Wĺ/>IFpz[p߄1Ľ=Wì=fP]@G `Y<ޫbu<ʱMk86P"%IIS1H拓b}b}$u/y/a\sb]` z=r#Ԅt6>kK"LzxsnU{Җ8˧hxOxtK %"[hgbb.`L߇s_>._kղ#3P6+*cy#t~5-:<+{y#zhcEp3k^ 7^C5_ /3uJ1 lǕ]cVӲ Y251Y843TZbEkM5o9⭇T6@4n輆X2 Jʣn/zjmF)GkCw-(@\}"KqJ />uZb 6X~*| AWWщWW,35=74/lߤpɪb]5A֕|ʣ<&&ioKQK5x!~~6glGK3*Ä|eXBZәzYymH!f:q_*K !U ,kڞ1kƖX#1.+fy١ik-F#kWuVGn`8|sH _AFP:UDIN^SKZSLwEu*Q$5~_&?_Q<{8R>3>^XeQE4NG4=c}k,#MǑ6ޗ,:~`d /FNle襳:~Lrbrէs^EcɁ_΀*?l*KroW%HX3 x&*c̼;g_CUjس'sz=\_en~}>K0.k0!UyĚZ*Ț%K^We3[:YEzb}z;, 8د[>zbBZ1cS <~SSʮ2;c=B  r314ׄ=uutNeLs'h2јj헔^SzbMo.]UVK!W8:~Uƺ98@|0Ut:'fI;łthŚ$ɿPUwghTZnI{/kҠbuf㧎N_hd<^C;1^,ʝ5 ZVmYw-+۲] ʁS,Ta$z|k? 吞 ^k{F^o_WE׳Tmnܸ)VȨv6<#Jۙ29E+ӷ[z3)Y̚J:ϕ?k]1v$;~e^V,X5IXr^fW!X-ヨWŢ)rzIJX?{H5p>ڗ2kx\whq?~N _G^BKu41v`cALq[Ba3Ef Wռ2a .h,PicFqWy(Q!V8L #2"P5ǂ`:qP4{m7}˷oL,jhU1%iiiʝUVFў1欻1 įZi1Z[*ިuGE`NrG M@}%&ߠXst_Kk~e4QH(JejK`zY~5tn,pw2+ PtY8ܘ-٢עe"Cm7]WZ[Sӽ }"/~׍;\BBn̹v3 Mg逮-767[2?|Ɗ,k%)՛RVH~}9 }\3h2PMY*ya뺞VDc"@gy5^X\]UUy^_ۈ"Xm= s=ETmif5SR030r0?r<-w3f}{Nž7"m۶ىRQQe{kٜ7& 6-Nq ޠǵn4܋U,ݏl ycb};˘/ƳrX!6]Q3""+vsmwA`I:-&x٦rޠX0lyQ_P~:[iy_Z~kQhGֶ}}7q5ݡ Y0Pv3u#F*ě/bEcXAnnWXUf[ތzCtGyۯ;[ތf|wcXzKyEÿ-Wcf7c+#Vt [oohw?zכ3:IENDB`admin/assets/img/book-icon.png000064400000006317150515074560012317 0ustar00PNG  IHDRppKtEXtSoftwareAdobe ImageReadyqe<#iTXtXML:com.adobe.xmp + BIDATx=pG#1)0 $kRb$)2IK0e=* (\I-|vo3/w;s#ٖNw"8PZN%}зCS{vE+qM}x(+ ҿ} F#X8d? ᅡ䑼m7$F8vԮ`m9x5ߗS]g"B't߻*;{= ;{8yCͅzduة/Nr}y^B\ ]N,翐W-ܽ_G& ·f 0R#1}'lwH*yh9-˙f?'9+H.ikd>\1<>VM{^jFJ;C%X5åWB.q_|[xANUrz?ҭۚحlK(4ᓢ9Gps?_ۗ}M/G0T^j_ EZD_(ܣaJ߷fnA#BEݥNAgMu.fI[-'PJ|[It7of=52glLw?ymOYga &įH Ȱ{|h$E˩[7@bhu,Z< 5T/ax̺5m(p x)pEuzC䷰ \+<ݪSp=ФTﴆ A/O|DIn=V!N|qˏ~ڄIjH/x+0jUu) :ns/PT#[\¥T` H fQ NVv;a"#/@GVk`9F)oxUMm &M(!VQpA0k3C EAyՠE` ̒':2G ~]Ʀ)㐁" pung}-TKr%_HV8LS&j/]J_.b֮`IENDB`admin/assets/img/balloon.png000064400000003074150515074560012062 0ustar00PNG  IHDRddG2rXC򃏀9HXE.RD[ƌ"-K[D?+5 ʁOHR#vj!y|%jER0P"$"6ո2sBd[~?dAgY%OiRo@)RzDbRdx]ٞ8IAN-{X.| >QâVMgOtT)d#QP偗QTJdF *6Lb[sN(/-% H"ktĠ pGҍ0T5= pfdz5e5i{ijS^ʖrIxMM6 ՞CUi,MW̩DC9(Y:"$,OweR&sʶҎ*I2* »=gjeZM#Cmpcx󒝭=F KTP9TZ5a);uR|Y& 9춾 !^."~z 9^N]gbr)8`G^^)̍tT#wڟ=aq#Ymz叹?.m,eea#(]4H-"<`7RL™5' }|qzɤI-uE* K/<$ BRWܐ!̶f(RV@C@ LjRBЃSV˴4%_`L2""UdkX.8!d  Mzb`#ţ<+rD#W _?`ΥDy}r[|r-Nye3#_Xf٣ ̍һKnyT5hn,*/x(7c16wltN1>+*>^؁ugh%].r?|َ==r?c[Ǹ~xGqd,並屛sƲᡆh+c%׆c5>RIDATxA C jzdDC<ϘHž *"*"*"*"*q1a /7 ì6>fWWUؒa( ~>\2\g 84kuwQ2X šߣۢ;Z랅AZC褹m(/HCHzjl! %_.zG$< H%M21_M?t6u(&@Tg*j%s "ˆN=ua@:[NR1*(J?բ:~d>˲<_q_M)[D QJ+@m% VD I/ef7BE(瓲#EhՅ95R^ԢQs E :EÚmUod(J:!z9{ EVDƐ,8tb(^sjQ!@OLQİUn->@+QDB_1e0 D/zmRG.-&3ϪG_1CQ{^wlIǒcyul V, 0'\Թ GQ.Sh{$œϜڻ 0EQ{;p=?ŋR`\z^\W1Lc-C׏ i)O49~B"!H)B"!H)B"!HL_n0 b0L a=~eKt[7hآ>*Zn&M4iҤI&M4iҤI&M4ige\.D)4 ݾ̇7Lʞ=\=DT|)Q}Tj㗱h集,mTD>O s2">%$UQE^pi28OJğUjbb>^'!z5W "mʋZK!Igo$QTJ`wKKL`5?C/<ϞzEj;1]g^?:}re 5vE+n,*PnXeF=*Ly(lkH0r4hNoݳȡ mj*1FMpL8wLÚ$xqd<JME J$bT廉#w-n*2DPSҹ QLg=*1j5WTL4KE+*b>!*W5 T4{NÚ*FT{T,IB| hPn <\2T P; z`+A+4h4p}wMhЬp n&4hx$[Go%RH1Bz@}FR ڕuEQ?[9=Gc )X<_>[)8Fı" mMMT#cql 7 \$ aMEj {p2<=VT,IBmnvt^6|:GLf01xCOC{Fv+'/sOB*Mi95<_^ O_N:olt_trg/0qy *11{S7&p1pdKÚ&ۮxhdAdp)$!]@['1}X %|{8r񤐜?Hz?k$9}*ǡRx:96y6&M`R #X=`oB%Rp.5HPdA"y pү؎$0m1rU\qA~-sRue˲A'pG]=a3 uEfHwK%?NJ]/3`s<ȭ<4pdKXQx4qiO4)b =:,9Ê1/G' @sez'( RJO +.BޝڶqPOBSP^ǐXQPD*^E- M3E' -CJl]kL3$V7JwH[|??, $F Txܫ[,vD5ʣj-{_Ow[|ˊRH[ˆS+Vdǁ#Jy%Ov V,;xC1i4`3Iq! tݺt9ӡ1cQr:85iT^ݐqxly31C)<^xW$Eܴ@6͜o9h,bT)6F+ju{")Nrװ;_w}|y5ޘߟIqnmնG?!ΐ" A()B" 1_QE%(B^ Ů q?Ťn@\T imeʜPP*"?nL톊s%)4/ēS{1Bcz(\"(.j ( "*H R,p|%"kZ"h)*PDSǖPVw֙(ΌbȴMcgF#:gSřQa&>m7P2PDX@ (bAŅZX1Ovoc۷|bfU1E;#y_E/ƃT(w7CӶ/(fj ^˂( 3zn/;>>3A1gDVx%A>T4(f _/y3EjeYlY_q%sEb]m4VEf.aek"p쌺gu|O9SSl.OKQ[LQX&R\~ }ǖupSZ޶)8֗\]jtJ/Z7oWG,%bCfeB{>Ah.3Et4bxupx\?EOVL7MD-i(_m)ґsy$̠y!ßOŲ4Gu"7bXTnlĐh5ޣi2HIMyɋ)R P;ȟo[To9HMxp.RB:/"%B\ŠOG|z5Ztδ^c"$E>ҧ&}by@1mB5b͑H%vI<K9}DQMNEWSPO %o?5m 20 ˤYdaƉ]Cَ-uk׾LKIλ3>/m-Ґ':.Vq8$ݻ4'\N9FAM-1}Eo*K6ĆXVo67?!j;|-v%ۖtbrEFa`ۓ&+To_XT7l#]iI^âdSNj"qhZ^Gʲ|Q.1铽*jv.~!|Xb-ZvYK}"\U0I H ¶ey} O}0op(s V(CC25IElt8O\7ϨnYGܴ=K(I%Ѩ3Mi?A 8ڮ-fuEi*p!"xR`UQ<Q]F;+NqV UW*!5sEDŽ"HP c&;%5`h5O2PD2K\neQ9>AQ=Y^ʳ(fQIJR[x.E1Mc ]?˴[Yۼ(hD*6"Z A0ZȠ!v4^-:)P?CWdeݣ:KS̛vL\x@S XBag:r$QShb|- T "8aFzżRd>~M^m]Pt@)бjh -CA!-vf ߛD6QN@ 1"(9& E HVP4H+j*Ҍ}ɤx'ȶ][X7.)b\#h"k\^n'Z^fRdor ó/CRI#e 4ƽk阜"^:J(y "^XEU|nP^'vfmژC{V~,g;+e}7/KN1Q,CQ$(IEEQ($QEI(jnR k%\N x("HQ#7-n28?9A"(H("I($($H("I($($H("I+).یgQ%c 7PΝk%D'5ioӴEcĶu1ÀiVqv qo`acwktOsvky@bDM >2a~(M![wNt)#gn חʬ]E26EguUۼV.OEE(*DQ$$QT$"IIHEE(*v LIENDB`admin/assets/img/setup-uncanny-automator.png000064400000041753150515074560015264 0ustar00PNG  IHDRtBWPLTEuOVcntu}ALg?HWLehw6>GLUgILW5PQ6?Psnw4>J09D(5CM\N^x+5C!1@)5%-8>HN+2A&2UZe /Bbdj'1$.+JP8CN$,/đHR_%/ky09B", (2.7@"1"*EOX"-%/+4>Xl&.9',4>$/ *%)2>!+4(Ng$4=F&1;!,6;GMghfZegfbf`Bpg Nthh^dd_*oiYdaLlgjd_D]aZhZhggTkf`j`TlJ~ kc8nac`hhiiiiefghhhggegdcfdfxdbebc ybhafcaa {b ~ }ήubdc qa}cgn̰sazϬ fD(UlI2m7"Aqˆ2ªQBu5Hjv3L,WXI[Шk=ӈWB:'8xN`5 o ~_ . 7=|+h; H B1DF & B5c~HҫOΉSPO\pf6JIadȍޅc)q1S46%Y%T+Eǿry%j "J>b7װxeLg9?V!ڻD(/gZ")81Y'aX K|H>YfV)*1%o1"WKM,U{u*rٳROι8 Ea<)IkCuB,dz6TDQA]:aht:? w_r5M;/9'ݓ;u8xr']skӽ%jZߕO<7yGi4>r|]t LX><{Ze< Z=xKT+) wr$Z]-!7m8 RKiAGe Ab;mCw*ut#9  G/Dم:Ecv^A4kVMw ^?ÈR "\ru]S14^e( aOhpQ jʌ3KÓ$4Љëh4!OAMf"f].PQP Ł1qGeL[F?9B⺞Fآ>ӃlAJun5]2Mw۾:q\UQ" JAHLjU^:=p~7 kk$+[4(;hixƳ[vs\@mmX9#Y D> pAfzᭋ߿LЙ9jr$m zfIyXlӠõ^^׾t`nC6v.eC#Qdwlrk^Bǖߺ鳂itc2 HJxiڞiH~1tZI}k5s NЈ ͏K2 F! 3t/8ho[Э7A=D .v{me谗;zŪ+qG}-:k|j1T/6[KƘ9.މumisy}|]zd[9A7v^_Zn| ,5>t]e\B1+OIg'H'53]׽>zV[ZsFӧkO)#"֬a/)a6#C/3F)t(1;WFpPE2b ST[,w Fַ%tkPO[xwFO7̺׸1< G↢X W٘^]=>d8v{Q.G4۵ GYҽha58vMS ئ#՟w31`/]dys-_ޘ4FʾafUYR-We3u/>[fyzM)x/SipG.xEg`9%y!z\dR©@?O&.ehe_]kU zH3Q6Wh!VH_ϘN}5N`3mYCu \0!Kw,GX|`w 軅52/+vgΰӖd f/nkOOJ՘I\*c\ _0|F;zzA6ܽ,GF7La" 1梞Q\FZp?qcX@Нz"V_{XPg8}߫oXj]t(x]Zs~~ASǡl^J`k$ X:{9H_cQx@/0kFUe3^rFYa%k,$UӤ>lf@zQȓБNgxP:./I#!d%^# x<0a4}6i'ҕ#$yi'N-0klJd;N[[}UϙMHkޯ#]G Oⰲmd}櫘~3W_#O2/`/r0H6KdZ\պR:\Q]67m!܅wկ9\c7=%rI)$.v,a؁&MTW@k o BG)ޱD _ZZxݘNcL%1v b AOg>Tz Ƞ*yYIzZ/:e\CG9oBw{ |Mts"|x Y*CQu651c7F}ˈhBgz~2KP𒼵8Do=l$#]_. :o]c`~&!Y%XB.J^\XSvݠ6IV:b]vTs {c#hI[ïJ~1M&cZre%v[yU-iJ܇ 6oؓtiuo]F;%jyh A)zHMnuA JrН!Oޑ,..!_;:!aPunH,O_D`hpe9v~<ӿ *yl/0-Q/:~*O7l#(%S)^RwG:ַrb<~ kDG(0K%2ǔu/k3Mi1bc) juZХDKc[P"q/ 9@\m [ 釺XOcsoR n\& 4|N5bLkހo P1ot>>؈jr͞JyrTgHK.& +#d==6&+-uSu!O`|Jɭ囘0 +;8oh9va9̉ 5b ljf[/mT5Ҥ dyE iU`#."w# Ps_W^H.}%i) LްGYÒ׾;r6"q'C7v3׺@#?; @"@F> f0-ۤAPpfJBG\/d֟pM29m,f"YsExA ~>`uF:u0Ds!hywvt-6;z/E[ ]Hwˮy5mJӣ " 7,ydki2{%XWS|8ԽҬ[o5(#" @⢴BO/6M|:sOKplWzamuVrmFzYΤ98i3 X~0e<2>r&|^y7aܧ1? 9!)'s ~ ?=_:RV 5Ҵ&52yKX7IK*(Dm\'K&3 %65ؚv!V@ 4`{94d.ҤDK{1Gncs/$l| =anZt/ך>gP*ҕß{y˝\?ϙp监Uwl}PӇ*yr+BA 28ZHIbP򚞿A|']^>1$ ±g=mÜ2>8U.{iD$0|HY3.>q>~aEr,yݴ׭6jd44=!C6|@Ba֩)L=B>E1rH釀w/K^WOUg dn҈DA#dx3.rF;.T9 ' =FztP[Q CmJ3vSBf +=8!#/h{ K]su!4}t@Z`gf>B*Lf` =' b-.q㏬>vpC6 tl/+k͆%$ctamf&/-U1 Ux^@;{Dc5w~_j\Θv&aɦ-5n9 @U%1Ei|Ek^й*WkJJk^ @-pai.UF;yC*#}dю ^v{h.ZTd#qnƌ3sGa 8HxCu~HBP ӲR@Ȥɒ^._t|I]ցϏR.&f{吽pMU\fSB jX)B4K"x=z:&/sP:ޑ-H//η '3M+CS4N$H@\B^M{O  ˇX ؋\3!yɋf4fy\Iqw}Ð3 %D?zki+V\PK XX!5/X#G:3 ļx:G9.1ƋJnz8iNYJ vjdIx"/O#sc+q":I~wb7G}{g&?)K^Yj䜰컆!tUw:_4䑎 MH;Xj=xogr6os{眹&;tj]RЮ@X[x+^ ^@|QE_E-[b MBJ$ * ("~d.j̙3K=9gZ%iWGI988}ۈ.g;ǞNIƏ|h:WhTaL*Pst0=ή*g|xz;wthUU*.UJY?Y]RG*|!*鐗(zDuWN\)8dviFRDN6lKבL=z.5kf+xRN_#nxĸ:ftP{k1lEW+(Nzg0 KXǭ]d :"-y/Aa k cSkzf_? 䑺|ƌW*Ktpo0F•z4==) R^%<eau]v+hq䃲Wy%۵T̤nL]lzuۖ W/7HtLOGN` K~wɚ^lWyz+6zuY +=t$]y۝diF]H:e,}48ݨkV&4^ gQN2vvOgIڀn=0wA]AR(bDIT鿦:]*Ct ջ#} cg|^?ÌFx:=0P UW^TAgy5!p. @R3Fl8ۛNQK({^ Wo]?cI$4/=Y!5iȌLaaGRiI_wP);Rι(>Nu~0} bhz }q'^d/ތ4,CM)/\MAeqLJpt~/.}Pz!QWڈ-Ire& Ii!NGYF$Կx:W._FM?~䶁Fٗ!C4Ğ𬭬ю _Y%xh4r|6GwF |ex '  ofwR)[hR)~qJ Ys( $ꀎ3;8H5legp6G +t-Ѽ81qvvuz,/4v6gNʨ0xYz20K`@#R^}[uTP ]oL\㏃OmrO9m04`GUS6xivu5rS0tFچ ި m3uõf cL=\G\`|Mߌff?zOg_okZ4}!t5Mi21@î4vB"|a<}u%;?ǂҴTzavD5f閞S^ZrZF4UX{DZH$v$mՄpn%7&,"z܍Bb[(80,~ưm+dw}QHzuT_-o"m@bas | I#FO%UdD||rY2F!df1z4StU!Ds0̫Uxi1yv^}`/8ûZB98|@OQ7 #h Q1Io MVFKl}գiu,[d {iu;x+}7#EԬ Q#&w:0R#FoTTH֥QqQ~*vkhh6`]'vq}rlɧg^ߎdߦ~δal1?EŽ; O?0Okm+3w>eփ"R,77xWis:0o>kOj ?'8왜Dg_ 1 ʶŰicaѳ(3h]`fr]ݶVK#1$E3(j}f+vu]60Vמerbl| A5t2>1֛-98Ipc91h.$kYߧF[0-4jRjY', qMIl+^|d얱[21A1dLj] {&"! $?{sBA:<3/{ Rw&;Np}(t؆&&K )*bn !!!$.pAO+gs(<@݌8NvֵёlomkGtүu}nm '1ͻ;o޽{ÝﮤYI}X.9eWby%#jA$˗WdE 8q -/n~"|t4wv=.&)2u>v,@B㗽Ig@wzm0Dхke++SYu@$]fy,E/ ̗K| d<'_so&r};#~SGNLOwgy.k}9;ۦӫX`opaƅJJUUY $i=˖!=22 Cy}E%|C)./0dv^ٍX[g¶LKo'/M}v Qn(MlZʺUe7eY J!_2XK INUB".2,1!RPתFAtz4tgX ]77}]kem^>*$5՛04VjjYK)9_*+Ri Ŵk< o%賲5\eneV5"E L~-s֊ pt`9LQ:6iWի^Gw ta0#0VJ^ U*u)-F"cWޯF(ZIu$uCmUeDa$J*I{qh=ћq'e"cŸ]^nƣ_f6(Bb+ҍVVJHf2QԲV֜-JĒx*;3q7ot!8:Ist{s'~i_;K=~hXBS*FhmJ*sX(uF$FF7VKOrZ'UG5k *%u]o?zsw` .X8 E:G7cRVB̙#N_ P *T aDh8ȶ(\Q8OS{nH1@aF(o)Hg1(]hd8=r|ڳy=c2L*N&.^< J%#" 6EN(inM,81-rc^4MFĊ"tMYkR\jB"2Q99yhvnP;%wv66vփ~@ޠwrhe12#bȇ!v•{lB@FsŔX!Dp,4,D gB Akx1Rwnnvt_ :>eC;d؜eW9PyN`ihOcc.&^@=P+,`(v Q sᭀ\i *`xa:cG}_u}v0 j f j'vPV6E%$.j$Hcg؞p=dT.ɠL;4fK8_.} `Nph; GŔ(xm>?} ƺosAYƫf2>;T4MKUsw:3cx$ QƱ =}-_9&"_:ufڎiҦd{e&QMԽ|`.T8$28́Qn.FHO99x* o߽ {)ž#[36J%&,V/ ںtgM !ɠc r}at!u/'0ƈz Ԛkںytǻ{E缽pPJJY}4[˨Fc B'ؘM:QB SPBJz8mƈ->g`a{p>=) ~w=E5$xo7kybbwkWuT\x|`C%W.BqBN#eN"q#Lbo3}KzUbI{B^| -:H\~xZ6Y|^ǨYk]%! =$gB BDoGEDݪ+}#K{fHP>Y~Qӵ qzJAR+ IB /38' ]ّ4IF )B%WyI6U뜌^ "aUfw8< t~~Q__fqxcB7^ nA]ؐ$U*856lY C5lDnE#a(~NsJu)!] n<3QfK8XkըiU {ԠQ57 8qJR(Mha# RDd'h) fOK9g2;`J2 0|پ.(kwH q 1 S7!+Ywױ%m46͟Μ>I~\ Y=G k#<}?׳꼜8m=-)8bKرWsnӧ~[1qIENDB`admin/assets/img/fb-icon3.png000064400000001221150515074560012024 0ustar00PNG  IHDRhh*EcPLTEacjonejijhghijklmmjkmkkekkiggf\k$ tRNSF`BC#q `PD0S42'+FfIDAThoo0TS e.$ }L OP$D׬O**-aFATݯsv:{(j*hy1u/k9QZ,m*5iZ1 -^EZS֠lXˏg [‰ /L ]$Z O0BO$nv݉& F'c&u\Cmh16)8T@Qn*VD%*Z:Y3ЩސNDƊ%؋N;*H`m&IM|%1փ0#"0edJj Eh!>3h.'Ubf$ZNՒ:RQ$;ͮ`ivh~<-TIfLqnE.*ۗoS{™jW P(4D"|Ŕ IENDB`admin/assets/img/youtube-icon.svg000064400000002622150515074560013067 0ustar00 admin/assets/img/about/api-error.png000064400000016236150515074560013452 0ustar00PNG  IHDR)θ5>tEXtSoftwareAdobe ImageReadyqe<%iTXtXML:com.adobe.xmp =IDATx tyǿ{gvwvveI˖-˲1G ! ! o(iI IJR4}$mhBh89ym@CZH q $)$dKeWZkwvvvW2B5wGGޕ1q`RG=t_~[fؿP2큥>9xA1SJ]J!*yLP+a<(t(댱JAof;!r(@s>Y!,=֧}z7G=#PJ꨼HY϶mM8 șsq] Bԧc=4 :vPU>3PD!AF u=9Q=9Q{(:qB!{(B= CP P(dt4AZJ`r.Dy3)LM@4B[!{{[aAFWɃ7Avj6d$j@Ojpyl%Ykd U7Dx{9(l7 ?c۽6-I-x!=Ex?7j_bt$iHbyC5C\Qa]b&+BGn瀯i<FًrY(c{6ߍ8ӹ^JJk"{rޟN-ۤuԬrȞ0FnLe.KU5йJ}ތnL]?8'RdFK;?vkG@Bn܃]hyBj-NAn!߁8J\ deE4?B ݒt1MiAl9 "{'N8, (Zcu E[~8C ;ҎL6h!:]yLQ7O=KZDd~ 8AS%\>{[#x'.;HXqop#ޙH1;oެng1"xY#qƽx+wb5U!w9_i S(/\86(>zYNƟG?d a_MKr*x_ފT9\dj@$xYpz{B? ٓ>Aas{^5rem]4%^Nڏ"k׋]F]'v!{{؏r{~JAdO2o渉*on7'n{5gS%d/+"{Bd3覲ԿfDq5A[CSNtMd]&F/2Gaq-nK7JP胗zBgz; oz ~Q3s#jf1tD5m?7ҙg^)PM K٣n7ٍ٦ڙC6YY)/7#yFu_jR|:_>Or & /R^8'&$ђ$GngHWt%cIC}9=v/n p6Ekǜ3'}E>"h}!8PoXp|_GncGث{ƻYlE>5ӵg#/bCi hm[HߤՀw="ބQjB!0)헊 }^0Ng ֲ4jCo{l,yqajTQ(-z>{VH_$o+gJgtcf2Za}##QGye[^Xј+!YFbi_Dc9c%g +S⒳gj#D4V/.ⅵƵ7F)٫ߔ]U﹇/ q7[g )(^Y k* aBb/*ZՊq3Jܼ!}QFMqʹi!3o'4{ϰ8JlzELjڟVZ"|鍚ޗqڡ">PGƽR(PF5M_6s*ZWPGW崓 vubb޲0f9S]- 䜼8yl/yU)A)Z|YKvG)c7)T׶Uv=c> :y}Z`sNR[RG?U8=M*C|bG-LiXsm/ ~79'w^@`9S!m`n^qoja`9'/"{A=q.L# v4s V1[ute(^m驼t.Ξ^UH 꾑gL!{GE[m@aӑ /UݶZ٫dXߣzNA)WI"y/½|G JE@5k $0{8s'$6LfyjBY27VO \<#aD#5^x!%0^bHGãbSNNagcVzos^EDa?lץ7Җ|Bjy+BrMd29s/M;6|xSQJ8Y2Wz z{RKisx>`&'goD|RѩRjYm#!}>؎J:PЃ(s }vwv}l0sRڭP{"O$ g[yRo-rYdY-\Idя{ tmIE9`DV٫*FCWR_ՙ/kW)K\7A]oV&0֊FV68IIY]^$ $X)4'wr)GNkt2-2b{n3~byÛB}jL&]ӗ{0|]?4WJEV;? ĮKn'W(6THm&-gCk sv}O xdae!د־E;iF`>3OrcwԹl>qq}tuYk@!6D%\kV=R:x7RYtJ%!.^)O[ ]S2O,?+elM◆_FUEy֒UW[䔾0Z-z/:l<MyEw뷢J^4 X[y] J sL#{g:˷NTki o|]{oteYWh?%B]oG/ ~JdoHNt威w=nFfa/Js'~M2/J5^bzr{Fho?[GQ?8=yn/x?MøWQ,fWK^'S2~ +nN'ɱ8D91&Ǡy/lmTglV:{s:F*]Q<{o>ub$$ZE`O=#!}ly.,9h=R*qwnIw(uVJHtdu|7cI]~3i@bXl9^zdO0^##٩kHՐB#{†aa=a6rʏB]'Z$9F`x̌{KZN$`1!(ye9i=2Ct Al:@9=L;@@WnQB=Jq0 u:䈆Nx3C汶P(8oS}tIJ"'>x%b9JX,۶=37Yzpq'!~[q`J)lJyxu3)fv mdSJIENDB`admin/assets/img/about/icon-partial.svg000064400000001413150515074560014136 0ustar00admin/assets/img/about/plugin-seo.png000064400000014404150515074560013627 0ustar00PNG  IHDR>atEXtSoftwareAdobe ImageReadyqe<IDATx]XSW !@";=,Q*XW~*jj[8AET60 a\[ \>}$gys9#'CTֶBpC#ϝ{ۙ/ iIEu'Aʿc7 7-v̿`<5ǖ2? @Pml7w`2lU!HC<)h4z!>Dk7RnG9%MBg(hhW%CHx5(`4!Z>[)2>߉_wBGǣ- 4WO>ټnwصN rC?96us8`]4L\)"*Hie"[ں4" ,@Q&Z$϶_yRe9 $@|6k͜o>$hwד1T$˾9km~.nT7mΑw3"l@5 gZ |_`v(81h~'߷ӏ._lG&|t+*W08KI幣fm/WѦOL-3rg]N/| op&_~$u]6om"2}^dW,ip|UT`o~Q'B_C')qAM{x͝׎^h{ygdHa E=A[\{'KfE<A3g̉dvIelؐK|e'A$w&j܏7  *[bm,ŝ3LVB!8p*7-6vY0׭{0g@4qՠkawR~lA_c|B %:~&L {B%ډFЄ۱i:|!ݘ|^ 1IQUG?x)"rA9! $BV 8𸰬ʫZYc==7qfeHћ$$i} RD::9Ժnٱ;7@MNRtAiceg4BRR\l ]3^Q֫fۢZF#Dh'Bnz]. "ܼ 9vjZWt43̻2>lIEuMjDl|w7~jb@e|AFRE=ts5:9Y62j&|TO#d׎È5ub|50y/mvPAoDۺF9+8"jN]`T;`I|Yf;(9ZkN>QN]gGS˼I%xyO?bO6E%_;ID՗+V٘Fq N(y\™$4U:mB4gv9x MMݳhf藾N@xBdO[旐ė| 9FYamt|'22 2od2[p&6p^3a/)b1J3nV&_d*#/Q~<Dw6;{"H;?1T XB# 4܌ymٿu!S0?|gHVaw#8\[}>C @zrJ: A;CBf l5J+5QX^'(;ZFӜWpw$S1uEDȘߢoCEeywvqͱRJf[ŝjrk눶>pz>ۙ׏J_VF,sX2 K@tQu6,*r#*[nnsa<='x-\n?屝jȧr9u5%k1LVs0H7Y?` A SwO~/ٖŵ|Y ꅶۆCKH&|ހ PգKG[9\߀KEuIxtƿP-UVZ+_U$)0<ͬ_U߼a(ΘOX=zլ1m] 3$zxl'!@MCTFAR,2ETsCp̈́PaӨ)(CɰdyJ&yE%f-(.Fm]ˌc7,&J@"sLq'ӴϰPĒ`LYмi ${LCX䕜VWW4(4>K!V79u7ᘔ&2$hhIJ+_+aw}fJQ9C|7uGjVe( w3 B=uND&!|kTO9V_bmx2Uuh9-@s[bu}j2D%T!;8RUX4B:Q \'2YO0T"u0PGuR5U^~Dom=9;s;HvRsf]gKnHzYnYnTaφct ~+]-$g:+B$؛)CYF<@͇C xUJ% 'JЩLuB SM~N4J]c3=mbvڦvjHAǪb #%ٛ)ZCI|ir. WGjSs$ 0t"K:'Jnl(h4̯LJ/߄d24pbuE9֣M_NO1S-^HҲk[5}w(PR3oQIQ fD|n' Mxd?s\ j <"\Xf@ >5ZQJ .EYGh>s#B}z/I mw(J Iܩ `jPjBO퓸 ڪr[;fphj]v7F<_rO/M8XN=oۃtOrxwn|+ROL7 } P<ŝ`PS_Cۀ~ 9p MZ_c/=u9[JA2y\‰ bf",c{ S÷砊*>csteF1Oڹzѐu=2?+y<^3#0=)4>L^j<'֫fTQc5M[OF: w{۸\@OIEYp؋}XT_)^`kR+!31'QfE[plO9q6zQ(~<\'Ue/<1gK Tv]mَdyͱc]=\e W4Z&- +/u1<:QN }K̭$ o}V巐Uwrϐ6_UC4mO+_ycVz[gi51< x{hl?!LXmՂd)(+H3?x 㟰QROauL=WaFk3?>+4A|oӽ!$}(8z!{~ZkĄ،3fEӾ <<2 kτ{ =Q0|Y{ͩ?97f:}썔$>hw+΁$0˺~oeE&nwi9ـU5nVғ׷ujx"wN˨8nTRda`H@Wvm3֫fӷWkx?h'o8u52` WÓE`H8WӉ~jva97Rqq^v7y*nO iY0AP*v_?*gnxH+ .Fu;)o~ yUմ=/jOLftB=LFVb|*k>Vfc*萚gcOw" =q'NG*%uCXNdfc2x B[c GEVg|Jقܪ?9:8==E^/Yf\APeTKט,ːphjmT){l\\` }7r~5WNtࡓZ ?>M/$‹]4>ʊnLb٤46jdžkRZڌd- zinV+m~]&3Ya\.$WeA.gvua ~!8~e!ʘLg\rÞ x!B 9@h"$/f{jNHuAnS*cJ99>+UXX{2LLx|" zȹYswY&%i)%)AH/eT x%IHgaJ ]lH&W׷HdU$!&֦*L噐-52<^t[R!& qO!w,N/:wWOJw:rB|'dy $1EIARh**%,&W0^ 3m̲IENDB`admin/assets/img/about/plugin-tw.jpg000064400000007122150515074560013466 0ustar00ExifII*DuckyP)http://ns.adobe.com/xap/1.0/ Adobed      JJ !1AQaq"2BSbr#C$% !1AQaq"R2br#3$ ?Y9kԽn"`T'TKCyR/McnJd4=R4 R<CsR.STec9"s ±V#>04!'qJ =1O2PX4AsLu4v KݚYQKHXBVHWs\@y ᴶqi3"@$7yC}'u)ENwHKءo,k <&{V٪uѸ5&v.28G;iZtuoiZi'wzf{ħ&L#M!ã}סHaZ4T%KN]FjYLdGJގdTA\ xwynfSSEs 58dMHfnL9[&֭_ I|4xݳqV-5Ja]ppPҮ,^[Ta·]ƻ]Nc!yd'Ty֛m@Qu]z._wӴ94u*{U>`l7>TZAQO /R>()A_E1q94}z괎C8!X 7`>%h6'g6NL6 ]\5H"V3rVԯquXP5$Hh/ 7UkdeNe_TSLzI_ަ.҆pvkGgޟָN5.nzD)( ZZr.9IFh=Jޡ0-=l!Y[Rͭu'z൯v#.8c ⸞uΠѲF 2`ũ!c!UMlaTk6JHWUӂcd\4]p[z]Mz3@}vEV:סS>^ao0M03Sa%.(?uښE:Ĉ*?y:׬m:yv~ڀO3SW$m!YMz*] w;]g!ccۿV!-lJ ;nSZUw>αC~GBǡQ۵񏧡/z1cTlLiRݱ%H6OaB׶T<`ٖ%j7h )7p(V%T?q $" =$zH :w_y@YmA5\J'ud&,)^ݦ汫 .ّ* ~O2P[\\bqGa_CSnEKϐ@󱬍 o12Rִ ]{WވGCrzhyp!n>d2qԅ* eZ+sHUo"gں Q*~k#2.;#j|B\a$ۤmfJ7XE3R1+[oDS$6c.)|ҋ-pO1)+c9ܨ=P[5H +:ODe NHxrb|T@iA]vWI,9Oz&"8f>:w!xjuW2c^EiɠDbg& -`.M$7$BЭRH FbFJ+A uy>CE&a֗2ra}D6]!.WqjUBk4ߺ#CD)+bһA9ِ+m-)'lPkGwPz.jN2pg ŒXikE\qOqRH:4q9|V]KIqg+JdvOD;[g҅Bi)ڈ/l?ԭPkjŸSo=zkm6lj QWsM_z"XmxPrv.I; YNtKag+Q\Z7pYk湽SgZ_xʣNSP2`u>[k$dc:JluTH1.eI+#XJ:yzW1XMe^i5R̂9a o,(ҁi|91SRBD"i<#pfdܻ[.?a\n\:jό8d=t-- 'n=O@ְ Ez$ZLd*(@vIözN(}^M"y)ґ)JDC<~JeH*iD뷽MBs.eCϭ;5, +PTI$I$swPܑWadmin/assets/img/about/icon-none.svg000064400000001421150515074560013440 0ustar00admin/assets/img/about/icon-full.svg000064400000001057150515074560013450 0ustar00admin/assets/img/about/plugin-wpforms.png000064400000014035150515074560014536 0ustar00PNG  IHDR0?p PLTE~>>>~z>>>>>~>>>>~>~>>>~>}?~>~~~>||x>~w=~~>@I~>{YD26B~26B26B~Z=26BZ~{_#ZZZv/~>ӕ[j7;GO(c0.2=#aQIN_vN?Tj&B^XdzWhqi􀬼^"PJGI Es-b#j'c'`#37Bo+@m2X,Ȉ\SMk5Bŀe$VЛ{9K߂Q^#߄AFTԀ׏zmw?G)Z Dw:\1 sWh-T-{>ĉcp8u?mW1M.M͐XhRuA󺁝igxQ{FqDj≮ћoc`KnDd@V<0X*b:ήẜĈ֬tTUZOR:%',pHަ}uZFE::¨â﵎ס}urod1ԼȽӻqK6ưАc\LIܬsZmMtRNS|a)@M}D8o ٸkYƝ썄j$]YQ"Ϋ2Av1ضPВXuIDATxԜ]H[W/j"郏B=aoq璻de/BL\!0YDcZAi'Z׍vخ>l;7$nF{J9?眜r+]6{s[c⎒TxKwwTtڑz {'w4ji掂FDC7fRͭQYo #If^'D[yՁA4Wklt Y"@bﯬM2qDCjjL„NIn5䥔q*-t Xd$W/'M^5S?,0k]=x_2xSl(,!\ЯP`~t$0`WZ$k5;U5Eu(W|T0׬ $(-,ZlXrӻ͎d Q: Š!%Y;MɄYnDXc8)! v׻ӂ "N^ ¸ mHcƣ" "|β!iJ +0TES15yD}F9ԫ ":ԋ[ݜFdco?2Q"-zB!;S"/!Kߚ($o?1u!,,$ulS"<c lD"XrG؃K59wm/RSgK\ߒE?7/翂1'ȭgY~ ?DU|M|ꖜZ{ʈ<>"S< lWQ<"yTֳKЭS`o'@djv l1^z-*Z/gOQoN],QpLvgmTߍ l^Vxz/<}9Y'6^l$f_bov瓩 ȷZ:!*%^H[)Ƅ,sRzHS3*s"å*5X]ƧOQeͳ+ehEʊKOzn`g7FHEceO=75F8\j8" <*ͳq(EFf̓YyݘkgډDtNX]WM7aRl'[m5U*r{W|~Z(+"*3,UzD&LDxODkU6$#8.zQ;f*M D'svTVFX} :W]SntIbi|tKUC(u@Qd ng7,&zNcW/]od)\.<} 3;.>dG(k.S+. qShZ0!r'?6#L\":-asv0֊\,'EKz^dT^Ĉ bHI{;W$d[z|y e,,L,"%De"~3U3mpcbӇg2ްJ,ʓ/e^Ȉ$$U,'@ᣝB(;*("P$=;X˄6iU.4>Eh ("FY@2Ř.]^J"=R)?;"`r,$?y,0wV/I bDDψCInY%=߬,RHS3pl&nv5""Ry߾;~{ zV"P$p5HόFl0 %uDo+WCbaUyvj& ekB`Yƛ^]ADlFth* Y8tO zo5"pZd&+h\@BY8Uq-@ Rq1`:* 7Ǔ XUEp U@ĄK9nGt^Ɏ}iY4-Igٔ7o7˙"1NſxWXL!UB%-c]ɷы1+BannPmӫX܄k/V/ҢI-P0%*aiM,W`[HB$4Msy!3eN:HL)hZslI'wXͬ,r0FD,tFJY!u}AVT'oៜV$2< HQ_,l %/1@R:3Zqر^"V&$b5=?ld54G`'8{_4[>G;)9&(+C/ B{P/zуg}0DjmM+%Fhh41$=hX(͓IPAQPtd_#簾37fR"3=" oL׽TYŋ YsQԐi[ֿLw#/;ɜ||JXwd>~R!ב!.UPk&! 6 (*W=zTZ'qp>q ׏ߺuI[/w~VV:ՍDs"eks湃Qe; 2,U.4ՑB 2ħbetem]HJ%))gw:\N5@P4 jZX)2;ɜΨ %A)q7ZEV̒"2IkZD|mE#K=`6+}`dId, q-i"q)䟃JSQJK !P<vNTM> AJ(l" V$5sb-Τj) qPE|p-@ ]bgDTD8QTS=E~ֈ .UI0pUnq1 ML}uD}XiZǖvzfMGnqGyգ RI^'7\nr1hf˴6`JHĉ.3$g $.K'QxEp\ƀӻEąwc-m̬u]ݼ6 "EC* 6$T i::;ݜo%Sc l^z'a?`6exu um\4PhCs#xktj'H#p ⻺իԁܾ yT 壇 /AC͓gYzO CV<)XH( YHvLJ" xª"6juK8[8+buGh㢖pY1{"!C1y4]SKSY;z|'..Li!;mq];c\w23F€ omV.BogUrv6OR^Ν`掭w  ޸S9, 6AʤCm8n2ɴgyITk44}}5QySI'31#>𿰩x,j7yJ_: דxJcH˂ǜx`J(NvTI14!؎>/:+[#{Ȃ%Հ0 JL.Qh^d31 F{ͤ%QHش(Y] bX-5|覙ARhTWڪSeTߓUY֖+v{`";\eoϏ7hQ?V@nP+e)p#Սɳ $'RjI26`^Ɣ s UW84A5eʢ(]YPъVJ8ɣ%73uT ߾B鞶^15_{|MZMB*I1ԗ> ?oޞ+L2e 7DpB<F+ PG8 `59VEP V Ʀ$qf #iH Kc`~b>2gI @ RI߳R ë-XBP#ԔFP"b5`(=0,c$Bi ,G}r vզp( P`&PP@0ӳ ( W `>54LO YO W$YJ!J< bJqm@$;9[?=)p{0< v3}( @)C bG XA@jNt>iǜ T3(^wS K-i 7U6@n4|1զF X'5$P2e,@j4'[/|aCڛK|#|Р m;7;~zPO89%  E Aΐ\FDa3@Ô @/ضeCX9q! bwhonMx<CrBWMGKĔR=@D @ j֊fu"p A6#maa, 3p-k $Jk;KI0@j pƫ*[x"exD(@nP,ZQS'c\_o|@!0v 9O tـ {ԡqN,Y$;b@?xxP|9d+Gg~^͚Ӈ{#@ yFċb 54Wr>N%{ H%6"@ (Aa4 5۬a>15JHP 7kDI|V<((@<,"dz] ^ۖ3 | B,eiXhX8P T5 K +h'PZ뛫̼i/.'jy gnY >I_Ki_~}=(^@6B)bPVxԝ_ (ᯑ]Fz0?K }MD +q[ hzõŮf1, @c_ml\P$Ji_vvΛL6r\*.?RܢIENDB`admin/assets/img/about/plugin-mi.png000064400000016106150515074560013447 0ustar00PNG  IHDR[YQX IDATxy\WǓɼd&3?f&f4cI&qGAQTE\AeqA EE]}Qwp] 0γ>G鮾U[sl.#No8z]eD-D3:^Yˠ?'zN6QD~Wa`"m*.X\+ @hGND/-ב'!6|e~>_ciXS;VTCʠc?'.ܹ"痂U:^.z2 V ^Im~Lt}nt( 迾7=Kػ?yW`Gv k(jxjXl-^~KGEt+gdQ.-9d&1!h YhzSn+rQaN 5PLz`(!*3ҭXd#eU0iY`X* y"B)KCJe6 I>!rdדR`-R |cP(t5;. {S>"Zk_Է Aϣ6ǸT*z"CJQ˜LQY*Qm ̉v1Z>fw Dm_^E{i}r^⹺loFi (._l`M+:B&Cx 4C!npIלI女Ȩ: =aX+x.I2kg6aYe4Z[c˒r3KAPf`"=0"  GfYD{.sƻy.tm,O: DEފ6Y%W-EV)WL_ؘ7k]6 { :TH/[B9t=Z`RP7C@?l|~dGT@H[u*!,{N 8W '2a}#[)C/#)u(u:w> jyU!=ƍva 6}o?dI*Ew(pwh~D‰48ӱzOsKynhZ "9%7Dq5 4=5:}?s 4?{Nx>xL)| N)93 {y*o;,?’Quh;g//c߽@lµGJ2r2bdj;?< Mf=&/DtH~%[-.pH! tg48CMy-s*okMZI#)<ғ2m|$ *)[ wsTo{0G>hw~Dތ&wvk{,3n;AMn9X;*nuxQ[-EJZ|ljj8ΏQhWun= u3h|#6֘NF+ )nogPhl-hr~{xVZ -}Blb_T2Jo9OP $eP3|:}l& TR]hT x]EaP$4WA kgA.;ەVގ9" /awW8sz]߬h̹O$goڸm'#}RtHF%mS_<0سfRW_Q_vLzۏ[ՆTKL.R=n™3gӰs~04πӻql >-zyGEEoDQ2_4pU4=>uĜ ᖳdԙ;PfJQn﮿z6Nnn_WDsjihi4<*gj!9) lll$AwU/y1zWĎHj+ vj* ^P ȱ3`' z13#%D+؏n*} @wҕ3]=[]HvNi86mVz5w<>QBv3SX]cIE'=eq9@w]B]?iRtd_gç!TKv@apz8ثsrrԞ?Syk ;bKW{UW0W-"ص]Ϟt dAKcƉW៙@HrAms@uF-)*_{@ORoGh=Nw'9![WQ`Oˣy&EiШnYFLfLJԫ&иNNae+BfqkRD,98JBg¼2Yx]"+m9 W-z|Hh41h9l$.顐UYfY 8ՁQYJ0T؜|DOj|J|G3U|z374>0kD{{5dq}B#i;kKT`?N{m\8Seu._i*4; L5:̇r6slOum(MհGe捬t+(6V*/b'~~7- 问,ؼ5Bݸ V,#RPSt xUl\'B6F./e|LZƻh]~vF l{+|>9;pv]`Q}&\ޘ7e!;'c s^H%=A>^0}J~MdiF.=;6QuVYU Ӱ@ir:0µu4n5p) \ujgq;AAW.ؑ^mӲFv]~Վ=ގOlOݻ ֝c]GJ^\Ք4‹篠38ꊱ&T0ZJ^0di|HKuZs2^/ g'[MJi` s4 g/rH,^κ!mo.vۭs{Εý`x0Noj$5*{‰_-$kKQԇ"4Jp(ܨ3ʆtz6)&$dvEB-/4}*1/&BeTgA0hb9ߺRdǂ*LTARc 6+yޥxߎ'MF/#)Cqt:Y^m;-pZJu${`]:VD+\ 5^&,( єs;θ Maհe9xTB2N] 3) qb \|& A[M]D:Q%]((%IHKgQ!(]O|'=vŠK% %C‹- s|{vV!tfJ-TVT©-!S.N`68(0W ʺ,jP-?SI~W#K7 jg Eq[T,ZݳE!l(Xr)\r: 6_1FMh2f:/QznFC%yf?Ѣ5aG.TVd*|`' aJY >71ܥB7c6wZ51X/BS8s^2 <7Q$Wizʎ"+G'414+igug*)j=-G+졕&U28ɉ*UbLVq_FH;zoQ^=\0T {ȏnUPVmE~&/J0u"Mu'kճ6b[l*,;=& ^n0LCv}2+,\O9}%)|O͠5fCgOcp/  K ʧ*گKQN0B(pQp*~Y9 ?!VFu)!,qUhpDD&%v֠ZM57#y" vI Y?Qiɻz;W mv?AqL<\* %Du=rᯏ`̀)702A@i1Z*otaB7Dm0 6wath5 AqmP~ӶW[$k)/ >$zy¸>˩W2{!e|b%/~U 1wDBGhoq0\X@GkAQ$tggM2KJX6Tʢ䊋+vc99a} ܏aDxw rei8GYn+QOf_ ɕ(;A_ߣѷl>ңL;hj:, -hJa$2 z4lD[}N!+2 x}hGr'wn 6V)rg AnC{yp le3F?fma*nܾ4r rKWYG 3XO7QF-l%~ȇahі @qv\$Wh_(S]JK^uϬ$FF"7$Cho87Ncy#si4 8LVG&AQ5L3}*auΧl7[D>Dh@4#=bKl!1u{`;T܍8~h<' LnW5sLcuP `? 7Q7Sl ‚]5TJXe؉hVM(n`Ꮓ akFaC]ݕ_Ϧ_wWi|t)BWr69Umrؽ?y}&`#IENDB`admin/assets/img/about/plugin-om.png000064400000132345150515074560013461 0ustar00PNG  IHDR\rfIDATx]XVc $˹.[M:ݢH)Ht`H vws /)8y> /p9C{EСC':tCtС:tСCN:t @:СC':tCtС:tСCN:t @:СC':tCtС:tСCN:t @:СC':tCt/ ͭ] !+6M)jLI3WoZ\:FƘ)c)㗙+c͕̕qk L1T?kd󞓒,fMNX4%b;CSS-2Z홞nqA- <T25UX(.]O׾wԔ^`Ds;(f,,hJ&?8N:PE`\Nx1la*/K _) ny=7&;t LYUDhqWi7F `N:fGޟXZf寈zz+Ԓ߀#':m"1K\asi\Sgr'iN:b'9*|solu @' +@'xDjo(?8i+[`Au @'Z+˷F,\()i ?rbyIIMh~px $xV't 7+6LJa3(,tP3dW=҃u T R2:\+Ui* ~5SP<~W\mF6H\~ٴg BgS ۬m&\zq1!Iu' fx4u G'< N]Gs'{*t>sc %a};c2m6H28BiPTe2*]Hd'=LJ%X H |XRDxn@z^U Wdʧ#Y_'t˾oL[!A2T 7n].mWO_~"r`XdaR\ p^!!Gu*{"ʼng)0jF(P|q_';@+0MSJVl0p Ԫ XOrx |e"`ZFD6pڈW? 7Q:).t Qx^;a'Ai|(wYMV3X,7>HS2LS35iFVCj!ϿBkbK[DBj1Ljh ",DjR7 =(C*:TyKq\bbeq'N6@X q5"2L#ϙj0Wa)9Mڠx`"|: )ryoVAcלd+bfv!R"mxk ֚+X ޹T_%ɜU`Sd(%D6ڸp8HqP wIim6P ʜ mO׎w]6|_W w>.^II1(QYG pjTl*([olAVW`< ~J{:#9|ܷCKvȉ}\啾.k=Ghc(e! vZL 6^T3^]nZҴG}Rt]xG"``2؀SΓpcW;roMQ;QKtݲsPΑS@NPc0C[' 26~1(!\w]c?T?+e_X$aQ;~JCßs3U򻶛ԩ?\5N1S@V9ZgE"%/E5`&5du _n*-D9W?|bi[pҿ+_j>?%P`5d- ϊ&q_ ijRmw$Z!nxD#hhG? 2偭2LM ƽ\. 0`2>!874*5OrIo|L}vt@^c v H.Ze?5rF8KOѫA'qju#>!}y M| BD?}W 0zx"&g mu-g,>w $Mvv?ӴirQ oh[-,= bNݲeROޖvI 7%؀x_ɀ ")Bc􂀠E8ﰠ1qLVIx4G>bp;z}n23AƂU& e?Sg/v*M;0)EM  3f|/:m7dkȰF+:@[O (ںm>EGs3kO6.NTlӮfjun>aZ.v1)9#]}b ]kZ Ū*fnQ@K 6S-wLXDJHݎ}.G*` #}7߁A&"zxL45IMXLm2YR .N˴ B`?)l&T, HVI& r5a IC kƄ\*VTZ)^]*JQ,VGM5uk6`򷚼. tef9Μ,R2;$w߾e4u7 `eOµ`om@fs![ܣ6h5p݆][O\f4nY)f+߁YԲRzZM܋/RyRLs%j'޴]t߈SgbPOa 7 *)\y9f=8m=a;׼$(me>@ gFsn^]7V #@Ym!/|fbJK јq`A(mw4ys/+%ezHg^{jm%eHY *ާj06MA ,Ar# T K[N|< 10Xl6c RO-&ݖ?wa5[d2ʲjcda'? ӃDUf#V|@;f-98Ht/*!~i'ӿ6k9+v xʯ{3۠ӞSy/I*Ggj|US1l9K[1 ԥKjܸq0˯қuu*AHN#4Ԝ(|2=@M%qLloZ>&2m ӧ+0뷂g/uP &4WOvk! ~S)++GSp], 0}Cc6_~_.)O'0+=?tNx ᆪ~L0W^WiIo7FSHYLTwR^o@) AyNl>C[,CP.8SA $s69j \ ?H:vlM!`%,_E e\CֽN*o0rGӑ#G봯s%\ս@O뿕ً:(3Plv4vh_X+7/+ ?-|73Ӿ W.Xޫ.늰nؿ]}no$ҥK/SV^(8>˯ѫmMGwRP EQ>]rX^nGx7 KNQ~L~~)aS+@Jŧ}6fr &~A WuӶcfm%[.=sQ~ ^^7yZ=ߑʂzw ^{8]f 1m!pz6`T C6a) sCO:+v3Y'Ck4H^!"yul;8cͻW '/IY.Lr?3mm8tHHх 8KoP` 9},y5GQEL~]vkc"`~Ff|*B:ڌ[XX}ߩ^zbTJmH{j_C}6:˧PN0pCP@4_D`ou_Rfmw5P\~Pޓ22;E+(Jg݇|ZpEXԯ:Z5-W4{?PO|~SOe `F_ps3 &ca.;zetl]bըQCN+cyXC,^H5Av #tRK7<)+./5ȵ%Tz6uqY߳2륦!ݻDQKb˲wbYd|9":{1v|^؃S->_j:Z|.gxO%Z} >~t{~FU,@DʼnǭII,Np|VȿVǏS֭D"JO>$S۶m]+3j߼.5j۝z@vQyD4t<3i{PnBV@JxmF6]i2!0lXV IyXU*d (v_x~2TkEXЎ#qqiR:vctJ\̓')4l,: sΚ+|j4]5 ]vyt[9mLsHxDxnY=lp4_Sb>=gH6ۧN)cpooܼ &ml]lWԻ,8h>b6?y@w.yc~Fwu9C){.98ib觟~Zj=gKaQ~E읟l,IöB)=zH2s0 "WW^j*݂ŭ=%ٍ6^x zXA7<C!c,kG!Md Pn7(@DYFBVc?daln,㉉})ry\V8 4ųjP:uf͚bs+sER}3 1JU~ @!~2;JK$m39?1/Q3r7x8Wr,PSs*Z9۴wfq9[#_$w1Yd$J-? XN V. x꽎F&X/Vx~䯟}YN +=Ҳj,~kuJ_`|Al;+,⾀Yz ` qJPFqXV uaZ R vQtDX_Cv)#tmVkpRDF̲;ddqcmm;Md+ť ^ ?&$ED  s`{_*~o5"iD M?6j4|':v9U2.]L9p<:Yu9*]Pf!{{Y(\Z1w[ܶiAR^9uY]+ `5 n@\=eGmT c(m`^@[ Q Ol?3/o_-i I?n @Md-vk@.]T|O'ÌWKm[/˚4A_,+j,8x/.ʕa8ל_yj0P9}:M>&fYN^*F|+mE]r9N tvcc7ל8㯈Vr:-ENˍƮK?9o8'mqar4=Y]An9oD nT5+NH ++ ޫթ~}ـ@urhhWHX;I%#Ql߉RgIU Lz9pZ%>[jEObg7"h\Unr'Ea"|Wki.2 ;,Y:ڔ(7r_Wf`w/ U-?Q h qeI}j,`ݾrN_^ݷ!W}r:ߓ kJBo<܉v|-IJM<nY: 1_a7kMـq8&r0?X҂ twTzAZiilZ?7OqgYJ6k[eb0 @Nypqx{ &1V ")46v/'Rqt)(v_`~x^=;_QF08x j~ 8s4(`[+00@/G*h: *g S jo҈owhDZRaTpozy<8+,w ?yw޲ Tn=H9/}W;t"y"2Dz#gWdqO^V;׮ .,Μ"?չn=+@[a1 A]M' 9_OK}mL<F3wE)0zp4wd? &rU(@9@:"x& VKu7]  X8xMuH=Jv׶][zEzӾEStP A!RiϦ]niqxKۙ ~ ?wdo*iY{1̆XFnI&) I@"Ee3]d62̲yxsq+t!v@j[TJJEn¤̾ꐐ-ҺTSeKl'$؉RJ)ӑ띶5 ;eTw^TH! r7;{V1 pPQHui'l5/zhLj+h8}Z%Osեﱆ#/FRi{Ś7yw3qo[? ?\nw._No /̜q.:>S.:U݀${cb5`$E5Vk E|MdXe. Y77 t/{q%AA#+3#Ÿ5S? /9'+pbJ)p̚^S#pƋGͩ:IJrPGI=+,\t1 t@-[-wNb l]g d깷׿@y_D-:3i/L)ItIw 8Y/VL]r*)AU e 8@Z=qωzdmǸd0m#pT*Ob5epM:O*{zVEd|ᒓ}M6Eb\pO^hǎj'K}wN*dW @C o6LCwJ@ƞds_SHZ_T"%;u?՞ujj6^S(bG;KQ+s8$~J(?J~ϧ 曔~K fEZƬN>yJC]J+{Bi&,eeeXYh1Kt jbO%2V3$: X9uqa 2zע`cNv(W%"juHS)S- ܁_?O.:Os(~o.k@LQRjN>(AQv\rjO{e+>M-fL>9NFRjJ,J*F0eټ@](,WQ4U cΥH?e0##Pwvߒʯ7+B/k3wyCcҥjn4($F]s^u6*NY0pVh7kDw MfUJ Ve&-O >v>f;}F#&mZ#P5PPџm`gaG]m$~AxeC"M$ظ;N\WT(?IHF!Mz,sڊLl%,Ӝu55Ҧ SXH Jʾ S˱`P@d^(cM ]CQh즪FN]i&%R>Nȧ~ tg(xaj6"_\V8Yq?0AmQŅJeE"o.4=|A-%#CQQ9=V 2Ųtܰ@gȢu.68 Xwhdp)3Kz&`;b%D/ Uoo[o&n5 D`&4)(iva*SU/7,'SU#QҼZԽ`#E,ʓ]mu @@ e\ ~TJJ 1qS= LI!䰩=Ym~W6Pe72ƴ̠5?=׊2 6BRS4 )}sU`J}(խJ>YSr#sCΓ;jM]k8ҟXgY9.JMɹwEeSzޕ@5*]s/{0+R'>11F! @"~Ŧ cRu `/ xhex &g ( Z?CN;eo(@mW~jo}!sWs;@髋D/3k0rmKNє`Di70 ,&[n܀"`ElaZ֕ⶸ3׏ ڰ~&d֬XBbGa(#.N~>\Xx WËmY3X<܆#,_;@٨8Ղ.?s%(hTUeZ*֥RJnJR&:Oaӑ}H7P 0gq٩((y9aAuOӫ! Zf%v'nQ(xo)5]d'zyy$'IMQuhM v :ݩw1^ \< %V¼y3ݚPtxi@-o,US|b\U{39vن>4J3:k̤&<+؟jFR T@ܔ~2 Δ"=)K5,6C~~9CP40T5KPl`Z& i¯q Դ@Ss9>QHوlflڳ,.E;5n'I/pzja_6&0lw4=U~>ɹDw UIƛɩE:6m* n@}B!^ҚczP `spivHk[l ϑ^&˯P 2ʤ%2E׭, -ξV}acg?v¿"U䟥Յsuफ़l.oXs7_m.~P&j"7V"G(hg%ZѰ64<?xF?IFG yO3kHVӢ'wi*#yɑoϸo< hECCҨ'iXh;OmhH(C``7b'\Lh]qZPMuJG\\uGDH87YϑE x=۟X 5I&^ \Xӣ_ +3~W/pwnSaC,7sΜ>]ݻ%{M9n=dq{==y}晢(G5G#S&2sXX;qsŰ |O. 3Ӎ,M1(hP Y:–I̒͠qx,MtZ]v&$$d(% 릒BieRJKɈyDhu|ZXHkSb .XBK)3mm\FӌnA[V6Ɩ 1U&e{ߕ<,'9͹YLK;ev4͍BKɵ XJCZf7/}h|0v׆x/˱nݓx8zWx_Cg; "$&(*ˬN7Q|*3;+~_S(~@yC6mެ_QXq9Fq N2eSchZ$¦~?,:9jӌ>P&;~J.Sŧc%ʤpv~V +b)s2qM*EW%GҪHZNia@(>5& R7%J.?!Do$j0aHr::}x$uU+{]nh&7%'P:V2[:O_Fr=ScezQ(8e0Ag o͐0p+%$8/2Ek翶WھU3k2Ȳ2ɲ2ʲz7å1{5/cy8.nVyJ5Eyݚ۽vo?@}Zko6RFؾ4Q2+9aV ͨcszCAFvV׺6/GSh]"QFB%J@sʀwp3[1PH2W%S|?$GVQ\QQOAVV_I0Si| )ص(׍{#o62D~ciĔ }Эչ!:\lV!+,؊l5K8lԛ)?acك ,dddeYeeefY9Tt{sWwnفo) >P||ǣ#oiJ(ԇuq: z3ERqm=Fp^N_kBxڄW9AJ2ԽN#11+E>9Dz"|469y2Cbŋg\GW?W[ձTE,q/R+-+#&1#W\G1??.([ȈlYoG,.8 ) q 4fGV!M~CF&ezh1qEsb]YX֊geYeeefY=~gս{9˔wӒQjL\P2*1\'P.+>:) ukSjSjԭH! )":iDj,VD<)ǥd tl8*i=N>V*;Z"Z`IP@WT;"}璓ʌ+θ}P){VA\0v0F W"b:A(mX!3tZJ҇rrPV2#Xpˆ pc6,Z^'SX_:QwSe+ ޸>+yzid稒"{ xd… > $h'fWC{:[VZRk?SAӧj]e{"sr䰃bp?*,.0˲UNceҚ&6er*s@L̔魔JwKWL0)Ow;/4'kRGkՔfU=zP34)2i\cQn4n-|ŐwKhΩrulO[$S~j Ҟ=hx 0>Ttptƶ2c.c% 6#]EG5*'Ơj .k/cݲe^9Ʉ4G*cKy d7GS5Wm]%D?J3ĉmt~:r$k+۷.v@[& 4 K: 04+&z7G>L]75L"+ژ0Ltםmo3xeZ;Ȝdy"v0>i=dM}aei,CêZ(iʜC픉s  ¸|~lJO/oY-<5nu^k-$+77[A4 eRLi4D7oO/Л=zOI"ʆ9sbx,#\dk 'Ed6y Mon˖ NɎ \k)sCNr/y_>+$` }؅⵵e}ukhФO}6O455$ը*|:>>4Y&YojL͵_+OrGPPIc_?] Qt $ yQTz6D܇WYJsUVl̈́Se HlsBFTU |֌խ@]p“a_ݚQaBSTK<LN1'׃9F.[_"WhfZAUMfǂOщd5Ef"/MI?̋cArys  +q2zh\㣱j3 *\;^IP.VjS j)S!<諒p `E rsXN`ߟc"5kr}"# ^//2%ȸ,U;/#e/9F:m$Dqa!ih8 Zef@sT,YĤ=U|3AEuIYk2l:WexuM1\`>ūM6Տcֳ{wC##53|C҄:JcM~dМ@ј'CsGd4yK$ 'rs[{Aao'\^Y@! ".dӘb |/gُwŷ7βū)lY*g| !L~h  +KS.\PPD/JCgPM `I&| f]- k"~.$ݙ2Lq+W`ܻw6"+oBQ j(}{^p иT@/9fcK&",#{?Ѓjrʔ\uY Ä`QQ8e b]4lڏ[ޔ=A`*7/<0|^=ߨaV ;4&:H EAKasɅwvμX\RV$ [cXC۷ϓ+6-GG,e,\N @<  *ʒƎ7,7PRAYuW~lϛ%ԂkHK es٤؈J{SQk:a^(ܛ"o|K(y$TVcJ{>(XVT*[d`]8Kh*kD:Zؔ3Mmy _6#1{gpsw~Z=\o6$G_Y @ ''ݜƉ&8]%2} b!i`9(fm;=+\ec`}ʟ\.aLh¾AWv/3++i>#j*k(K 6޺pj,  {!oǎ?f#B9$),.c[&T1Eۨt .7&_0M]v)XH`N_9[7Zspc&$ۮ&V|$ @(E%Q>gm޾.SRrYN(&-[\nk >ƊXƧ& <5 N׮$ܹShFNܘ~+7b$5ؙh?}濺 ancFg)#Wu9yr92 ൺJ!h-aIJټ3iފ HHEU<_Bs ʗOR}( 'N+51"mq( /ȆᐹQ]&\,siXRDsӌɽ濩jL5V .*"*]A {7s j3ReMyg 2J9Y-DS޷ܵFHTU)|$?]楩qCnǎQ]@&5^ٖHs̅QDA˩s\6@2+*CYK:l> F=^ˠԉ;<ߐpDvu6%@`o뛠>FG_7I7 ]ݪK#on-Ԟ_\VO_g@j *uu;n*죩z?sG+"'*ЍgE?Cט,7APE!!lH! ~ K ;Z M]P=D \E{Z|#\WdfPCl'Fx\&0))HXzQQ?ɢ=ߗu%{Nm!̺oS7qb~fU}e5{, ?#hzڽVBdT4!C &I pH1gK7$]~Rtx#VR ! uj.'*3aѩӫ3ہt qĂT,0|=aORL.ĠO'٩7}QJ+u`\.%f ׮o6^BkjE7 @@OMT|U{VЅЉûfNpa: ^ [_ 9~ 6>%QV=cǪKWTo4W 萐cuze%Xpuw|5#n"{o #m=>_ʋW%!¯^Y-7uw峭[ Et}O=|%wΝP!p( 屯XI<[F;23wLS^]i5.}F-]^QQF?toʪ}w7rkN&)ON@Wտ3/O`P'6}Ǎi%}d$pB 8K'{ EO739g&b|[N\0#>>~s"cѿ#^OԔM+ռsQb&!9vR= $T$_M&`y#TK%ԭP;6,.iG/m6x5#}&^krv.ɶk&*=_Q[O_k=c_7*^Hg# Œob4rN'~`V). 9l$^@oBȫW*_nةLqU6)Fw/Q5={B8810z4dĉՅ ˌdv-8_θ*ڶ*KѓrI\ttS5.-\PI-If}}0NH| ({_~Gk 1K>plT"q9]vOĵIj郧pJ_Qېw0-rQ~; 9oG>}ϙc5s u: CD7?%*BzIfWCSelѶ׺1a(3qn!vMyϏ#1a'MS{z<82ZmݻOm-? i`-Swic(:䲚4{(J|_ (F'Mˤry7o|/l|1@q̎󒇢Q0ZPɑ)T4B/CB!}[)/s8#α|#HTkpB%m)O S>#=jz)Y3 DSg /Bl'Z~\ }U@E%#rl0 ɩ'cTG<~q'm(@|\OMYIB?= {]2qJ;ZSK?oV}  & tٱo nGՎ3 @,r2g/#}NV.S|*4m=Bgk!) ٰ,-hXDZ`=?׾zozm:~E(w!tI RܧZ,Rz 'eI _>L(鄡N M }i葩?ĸ[|fG (!96Bck eiGԈ(nj1[1&F\yIsQy@YId AkVVc({ LݳZ_V5 t :[%SG6zmZڀ=Z ^7E4jjUjh+ +WbO}a`>|fVey!4$촎RPUƈuNBv ք'QRQkw;݀vq@u0n$@'$ON9c@\~.驫U8hcX?o12gnX؇t&4iYjA41usR da2F?ko,ӷlyCY崏+hӼkݧL}V"&k\BZ\蓁Z0w }Z2HgJhYF{v Zز = NvL"ƥURܐU_Q"ǎp58ܒYqj랽6ho谑3k?xL>fƎs$ܪE xRJQ:'7 ܘo=T[F󽿰'xUӴZOj>Qf1~bZF.?1vnZ4bZy4_gbZy_BR4H.SCJ}O41F rD\"cSg.!>wNHB f|*݄F^`U6Wx['cX%*PF/WCGn djй=C2]UGIQ_*T)yU/NbZFa|Si5Gp?W\ ?.9lyoM{?%50p6ZbZESzk1;L 2H0n:u\kdI s#/8y Y4uq3jLV&-Nߊ՘i8(~a$tEch)D:,uwJZOu:BnjӨX&7 LxM*kRJY Cц8lIңGm56t$AYM F EH;{=o8|fIBoNܸChiGOɟ z"٨$$}'>&U<9:|7|o\/rZ1ss*j@Q? @Yo >X\{@ו@Q&8A&7B#$9Th$~ČΔ荸XvH )_EBGԨ o6fS0?DS@ґUk#'hQqkɯk-ޫYIeӼJ=X\cGg`/>THX!W]s*P{EygM=ElE G,`2@wZ'm@3 ۾GTıC7XS/ڶI9y@.`I㟘T{&  b&|5imyhm*r"Vz7i G\n*]K\j7,UV?r՚FbOh$EzZ s|:k5qj6t]kP7~+/]Zٖg]uzKf6E( w 5$Y o`ڸs_Rz{y8٣UcRofbp!g &LRcw 2W;2UmCCibN^(,̈́Ta[#ⶣ4jpZ7nM0*qX/UJ51S^ɭ*t掠[^ B I 5U_/JGN $"&B9~ef1h?H@ fx{=z';v!A\<)ZCrKI衻=RyX Lq1jg j9AІ@@LT$w14AY_=%'t:<]+wU^oPAk7ĸp%-W<=td7@FIm.b};.~RKIܟalW$ G%AM@G`'6Oʉǁ"%fg Cw59r}rR*J{eTkϚ1?IRawwx1X(5,n2vjR_,Kn>UI)"UnE0lyJi7{lE 4@'oA/@+t?@by%/ؠ}w/FteDJ 9 bpi-`ظ9)TjP4Rw-yz1tg4!Ȋ24_ϲF\Fwضl%]x5R)_[vOoNv_ uU}[z0zSYNf!<7& /z U77xѵ߃ŷ1ˆ#4*"@AHA=#曮/7_߃V֘ɐ* \ĝ%>/gf 퓘D|YRMuS'9&Ō&.{dM@0M `嫑pбEt$~zYoji244Xc ?A`RFwRmitu=7;TP..]:q_A&-"՟r8lō-{`șhڡW' >W'SVM a 9ALJr!\ 0!T(7T%V=vFYn\QsR:i,45@0w u{yvbpȎdΛ,>k9 n:{MF{MT[jk*uq"*Sg rI?c;:W:[tus1mhU6߹jP@c.j>YLfzF ]1+IgޒxqȢ,imAi6WyT/6\CƟ@G\$ W*AR"1UX*/lUKLoe_w"/;[? PR;Dh0mq{pi[ޭa :z4|7͉"6bfOy^{GT9Mk-TYf{]˪f8O R`ʩϿ}$Dj+,W^^ZJ*MkyqL rYEf9 ;xP/`A 7Ņ jx0GwTO V8[)?kPxgʪW'/W^&B9OLfF0Ҷ5FO-O](Y+֫(߳d$䞳 ֓g$s9n? 1c#߫ZwQ4F ]ZEUY]ljgYiE%X ᱬ Q*3} \j\ͣ]%W]0d 2u:JA>WɖsMNs-VƅRߎTD{w#=^񳯣<Տ` 2ƟLӀ՗355f*?peAb3v#H,qMaƣgvb|>4r8 a5Wf%o#]:?˄w3AA\_ C8,v)=7S'MB-xKKhI62I&ERq9y3qM,V]5]0]ӏ#Z Bˆ" 't(tKzV1B7J.(./yAy(?l5˟_CLAՍ $nQ9bŖ٠b%H@NdwjlCͬ;VNlض9 p#/ ytޱ)7x d#`>}>`4vNhYA0H+P+/;‚ O_6/棾OjQⱎvX: wPGyREFI (6! mWppBIZw s56x :`gEZ_ ]"@?r\8^P^ܦq:~6C}ҷej?u? +W ,9@)[[uFl&5 02$CCnvVsaW % >\J^v8)ɧռ ۤ,sn0N}/[}1[`H Y<Cs |*VURmDw̘+&uNsZtoC Mͷ!9A!0d0u(=e+l^L2(W I*C!we֨E[8  F&O$8/v;QxM>G=^)ؚ Kd!hT<γ&yff,+V+& 7ҭ1ӤTcutw_Wr\,._b=%G@o⯮FP?thx[B9"lt\P~ckSa"] s b|'=~4_@> 7so !Gj@>Fl='Xbyw3eZ=}|@e'N߾}Q gŞ2.;Ks\б@$tZI0H#fv0#iB?#,aa%C< G*pj7^KQ-O<71g1Gx1t+yi ? 0JO 3vUU]RպO[rmm']XܙkS~?k~iu@_tCvGf602k* ߑtн ,? JnQycn}M[ĈٷOIx=7;2,sWf9F&?]V?qWp"Ag2Y v䔔cx0vnLzlzW+`΂{r;A?N2[5;9No2uOt5+Y 0s_&:~kaILMtZOgrVKf܈Xvڊ*k귅Edd3DY8L<̼m!(a2@mȥa'-`Aj  ⒐^Z( ̳C2,>*o1|nۡzaIu iL{>~ǨwVj Ot$g 1~}yXiGl? KjNu\FjG=+J8]biC%@Pr4Y)Ibг&}nSg=PjUPz %zfb1w W50;i5acwJI =m62ڠ}ZU\@gf|cyјp 9:Y@YK|D`(gI%>+~<Ggjl#r-8 yX4ە x 8#ǧ @ߖ  !t Q҆p 2?{gx2Zq岔q ;0R^{770nE+RZOKk=j#i}PcALROtStT|GM=Wb k7az;ZHM>v#Guy;L:ٲ0|p{!>_ ! 2]U?N _P7%KDa@cr^ғa6VQ ';I T'Tz˿C xwn~KY {4.4pK2{ʋH_ 1SN4dlɄ |k]?F`䜔5ҘCb,i h,Hۢ?+dFFx,ْdsQD՘CL:_K ^A[oRuS mܛݩ \_N4l ͹ʖl1, '~rr+\N4VVa-ϷO{UA 2XOYP v/.a ^xҵ0Wz,}TEOX|y uNuǨ+VWU6*qir듊3~Gq*vZ3We=^RElsvJ8ωmC<`d6X1@boxanZcJi-Ì2ZIe7~qܣ˭dBՆt@ay&|>C5?]$&Y'\~ _qJ0 ۑG ZHt5|L?8-AS&4c6mG q*n ߩtV}cA'JKYrҏKHZdO/j RҖ7hSZeqy0Zjr+zg:o @4ૡFDĭrȈZΨ,nK3^4~X&k:V$a AJ)} i0SEϕT8:߹+j༎\Vt#̗Kn@o5& Q=h_tʉnPGr4VɲCb|N]:P:hvI?xn"t혉@ڔ@ɿvsg//pW>VJ |v[n-פT3a\.0H<@^S]lg@QslF`K?Z3_y+p@g_wptٵȟq83 ]$8P 0n* PVm:{TtNHOQ>Eɕeq N[>;DpwYT޷RگD DQfRDH$3ٱ ,D\>g+CutTu˾L@fDSK0yYr"t(p3@gtn 匔t9+d-{gk 27 fA#;v3<:?bחq"?EUe%[WI`{gm:-:I)u -fGwi|nClH Iy^kj{c~2c<>AgԹ ՅKԥWdAxo F$,g-t݄/Y䢌2 bsF1b$ C<ȞNn6 1۟œbiZ]6[Y`ڜlU@B0tu2m,B ?acRTTe.Bbccߤ椫>uSrRp Q`".;뮿96!XwwVYQrQ )S)H~[T̹͍G*9ڀebXEGMRZqz.A0脢v5PIY wJshܢ.h"P z}L.RIL=H`a3QLv$] #`,k>.ȲCFƉPߧxEh5KuF#'mw &Rzͳ]2aJ!,qcIBzMM./:’T1:MaeViO]glwAmF~wmTNj=bb=H-6X [: }ƓV6y])A ohj/yQɯ Xu3s9?@~^2!]DC;:,) %BihғnuV$*Y(Qd3v`:v!%K@ʨ)EG+ gJ校I7w1'[)􄹗cg{z5W c90laW6l8Wq*q^-nc^y2<3ijW9?f^?:9CQ66!{PM_QS K`9it3lWndȍNJ&=Xz;yfe330BP%v<59ᰊ\ vp.+9Jx$F:G[novYӰj7 q,PӰ72 7dA9V%~?]:t9Qg 6+4;H)D+`tuȸ$LXTJ=0mȤ]G ziE0,੘KaYx Pfc!Ɯ ~tZNMG򉉦Ɉ'-A|dӌ?#~gшˬ>G G q3D+6! L6q)7Xq<&u@:xx?|OH27|5,׆^׏ dV?W>FgDb||.5`)Ȅyb06~OG^4ޢ+?P;9`I<߫$o\:QMgqV̩kB.?+02la [ϐc0}VR+g߶%^kv6+nt@6!}oVR13ye2\*RPsBy -jEw-Q\U8FGժ<<ƒ? ˯~W_W^ᕷiϿg_~w=ŀo[}6ߵl3yǐءWɝzީ~J>lD2f-Ǣ5Q# &މl<8z 'Yyx#<*:b,y!bDK"SR2 xL!7~o'$i$/A낁_1cxxM~ I$T?p= YkȨE{,\{ھGIDЦ]Zx|c;hiaG0Roo#EY+Ɵ2l= ?  Uh5{*[2/zxƊˏQ6ɪo]7j2X`Ҕ`k([ȅ7E-cdRFqqr[i3@kW4?W aSpan%J)Tle˗]|sՀ=PA5k=TUu^k} d:Ԩ[i35߰ iuxȐ<(R~|l:\|~oPڏuzOWp/{:eʕUlj%K,^_B1ڗ5q݋׎׾PY/j%Si%]K[v[-x1dA$n:'?FZSֳ^g ۗӺV@5#vG B9#@oh#1Ɔg!Lg25K<`|<\ |X=C9YSjd#5;}@&Zk( 0/C = t7!G-mH) `Y"%,>RmGS_˓V1l&k.ַe Xx"}buzz[D6K'7/qގ-jS>ϱ-Mq$>WY8ͱBiC\:c(uO0Ox q\9q:n)z{ײ?a} 7G ƃ͌aN|yܻ`gT4?@##UR /0ј\R9 LmjQ$6~[r {U/~nEԥ(ɱ`G4quiBcިpQw$~dw]{*o jbo& or3b jԱ#nRPx1~T-n = BͦJDa#Ȏp8*. ?DxwoPwyL;BW(^lvzInDsB`x4n+mR>#pC?vulMn}K(itnōN'@0GyQa[s)yoņX `^:X>-k{ ,i&CjU5{5*~N4zr?Ppͧ Oa> U&[)~庂tqQ5#\vmɧQí|WӲl8zFt]Qi2\u"~pMͨΡ9z-sXΰ$\e bt;Tr-RJxV+W" [H& rۆoK~K G`)SH#ȃ=PjFTA7ɧYOlaSU +k\!.g 70,ʦPrj[<7m֟u̜bKv``T^2I40 5x q:ɭ6x6Sڰ>6rAW5mJsBZljutUjnW5t.E#\CJZ@W ,aXYEnA#?z#l3\s-FLaqM&żEDlwcAV0)ƇQو|-tjYGl^6 R+ inYoAS rzeM:Skec7,k9&uЙʆ[Vk}àA4.ldg]q7vfo ]֝O:n"VY';qwIN/+fu-rzf\Z#i_1۷IENDB`admin/assets/img/about/plugin-smtp.png000064400000020307150515074560014023 0ustar00PNG  IHDRkXTPLTE9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`9S`Ȁos<6P^ʅr˼DŽ4N\Xd{E^iaނ@RjsNgq졶xc|Ojy(DRO|8ʿûsmjWrjѥsZrzfU{4}if]yjDҕf~пǸa}赉Jåȳ{p°⺕v̫Sn}tdԕcZڅFìθ׿ǹϢz֎UىNDZǤќo˭иʳܢsR1tRNS 3YbM8k-'ѱڌ sTEĽy?7?vHIDATx{H[wǯ]u}ѭߏ%˽I$$P1uڢ"Pu ?cJ ڲncown7l|=9Pl&l&l&lۓ%''|k[bc"K[犤]o_R_#ve88Jv+P7Fc1K iT_fvεH줢gB$@Np"@> exFm^v=< `u\j$8DE31';XyP=JE3/< @;hnb-Z} %@E/.}a=zΑb .T%bK MӒQ,}/@Li+Ht%P)ى"qGd Ay hҋuDE# ǥrqy[B^ . D-LBxd,zȉ‚E08@5!U*8 t`M6?p1v lAUPme`rCaҫZ%2P:XH`Lf1;+R!)mG;@4<`}%lpxOtA5O\ >uWT5 *W,_Z|ݮ{^ē$B y|uCYkD|dV 9*:2NSc>X֪n` Sg!ᥲ|^ѴVkz*qQwd3$YȜt79vY(?Q)?M>Ғ@{URSp[. &EGm~(Cx 2' ,\/_M!A+*]~B Q@Ӂ~ #I()~%qR.` ;]2wc Lw WWjhY"Vx( τC&+x-O 0+p2O3, L$  [ cd`X I)m(`xRw@C,Sx {RIoe C^%'(e# wajPa!\jG /bsI*#4MĖ8"iwy>dy륆<3K10fD[HxEBkX̴v!;dɯkӱ\mXTA΢p"z ~/>Jy5w@ |%45Q2#xb@b\),q4dqTX T^fzZ.3@%4sj(kTfM0(47)@ ]vN. / (mC}Ygᳪ_3*fT I'I2G|C= JN6t y3q_6/-'ON0vh@œ6[M @< IyPp8!ڀN² `M:Xk--=͵6 Jˀ$@ ԙ'*ĭPpY8mgtҶSIL2V n2ͫ aY,#,@NGO{Qvll"<-i`5s/+_pcaf~jjj~f0h ugΪ$.4To~"OE/@,ƴ 0ol܌,&Bŵ(vNe) p28r$uxO$ QAˡ MgD`-S_q@l\IN\  ZK+u5؞~Jf9;O_NѴSX&%| Rg'XmjЍ(% R)ZMRXcy?8['@pN#pH3W v `+nuXz"/ @6IP, uy9fӌ5bQnԓ^,Zg_䔕3_O >>9SbBF^X!M^z&=v03@5ޣ0x78V^6T3l, A 3p<t" k5t06=wu#Co$&,̜T`M,Y&`"Mz {#AISax(wsya[#^L}@fVqƆr]ە-&#mv~ 0(@?g+gR|eV=edKOUyś* S ꖜ&1NZ2*~ O${E nF T2wMQ{o>D! CB@D$)e%GR"J ]GĹms 'DՓz|ݻ[Gq@<)LbEbABvFXpŋ\?x'@x||Q3LkuT\z.KB0\~v_(AE*5(>5}6iPq(/$`C1!_ ˬ||HƋ @¼S7 Vh`Iv>lO?IBX>*Hh0g5V/L^$tN`\ƅ|X=mi`hD>XHxeI&AYdn `1 xG'KUq(EOkhEY`-vDE g147Vޚ)2om)%@j)s߯gys-W#ɋ0RW}BLG߁(2 Ik&Li[&^$ aֈ0GZ͞O J+z6̚N\3-{Rdt{FO@<'s8NWgtJOI p/m1`|:gZkḰ27_ke4Oc}Q>a"\)%/ƔTh4~Wm!G 2!™UF$Э;Ef)Go @ #iGÃZk"apL/+u3Ok 'AFh0~7>q %LЋ4MQlI@c+ BlEne^vٿ9R\b2h9LF]yUC]$"ΐ?kXˌ\*}Ÿp14Ͱ@iPLRo^'\0_h s )9MHj=B֠79qduUT>Rg»!X>!r&ns*Ox }7QZ6+Hzdz(z@R`.p@fR^h2e.g ~~JP@zt0"MWuiLIߕ:)hXmJQoaD+ mw+06=F|r˥9ӧ1{H2Tu˒6; ji 8;n2]LU@G)'0?C_D?!U>*Z yAOY楫(V,询cN49?Caa\ {$@#w,_lzH'!@u5"hi9-g08 db%44cی~wli\&ZB5@7d gh@&փ ~z } d̀@6VO1'%GM0("d'O"l AK& p | ]TTb@;PoCDp ՗/.,J&v$zA 2)-f0R嚐J0@6v;CIJݓx,vaBT4Ad>e/IΊjGjXCZ Ћ44Āec5쁵x$Eǻ6#93c`X{%9AK~PHUi-X"y@`NdفV+b ',,h|p*$)zW?GYl,  ֩1G pA.z[ 8P|2]ڼE}fqQP2$d%eo;[8P`s#( Nu`[S#5W677k݉n֪f>XwX11K'92gbS0=0 ]7m!MHӊ7jjd; z&݀8lOo>coCcr$}vn2Ftn3y%Nn.$[V>T$"$#ea]-U06D2‡0lh=% O Kzx4?q}ۓ`vn1%!_l@FTCjbr]CIqQ$V0O$cj8#P@̽x>au`u76srf8*mЈ*j[(1= P,Ce] Q 36~U֪b`]s\mS!.&̃C'Pr CL =5{he4WMmۤ-+JMc4Dl,f΢S6c̶VvNmFFw;X$X9CAB}M 㽮wcU$>x&n ʀ2U'Q Q0d'&7ʸKl#?V.)烙S(a&cC@qzM}Dqt%x, dRb^;^`tm J\84ME;-X247o(4wh=`磅swpeWT8~.@pd:*}Zs678}PRDGQjMi㻊Ю)]Q.xi+WA)6'nt`rGis=?U (}Ii4Ǯ=',>IQ_8>+`PO py~[]&+V9ahñ?'[|Omsz[Paf+ K%;Forh]rHx HPq8 ?W>po]^8ΡASGi0 =uU$sSR г~{7Рp#%M'#sNg$WRj%y^>'WSJ%o9nEy#CĔKu%E voP~&Iq7Ji˳a@"|L΅a#[2- AOA+FBK8be,Dȅy^X(mQ3c_ȵ sd|6PABhYQ*|T:3TY4ܙHQ4jScjF%QQdN;wƞR%䓲"ѡ ~<'Nd2I!I_Vm ϵt+*qelgfW$xxJ,9F!Fllrw67=?a:K<1~7\6gZ}o aTs?_j eY 7c"nIENDB`admin/assets/img/about/plugin-if.png000064400000041564150515074560013446 0ustar00PNG  IHDRL\tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp ]l[?IDATx}ieu^;zCjNDp;m[ 1C$EHH)DH$H HlA?Enk蚇՛tb֞9?_w޽g~W#x\ LS6pܠ| K?blt]t[MLUWyfoY?#kAN4}nir=t*>S<}2f ɸ3iH$s<zMט" H&HGР+Xސ%ܳO-UX^5+~ioʍҳ]r@9'o]G27]M;GOë&-GQHI;p^D&$T'D:(%o E{ūO}{Ѡ4}^&b8K'l^m~Y{ V- n2%h-k0"H{^]¯,K^s%"Zscx@_V1ş$Q1`#@v< ςjPQv{0yۺsNn0i^i/E;drmॿ_VPR؋>}/ OTOy9/g1Xhwϩ(*C`c ]TPYy z)t]g3]X>N,b_t%@CmY}ӯcZ|%`7 /0 ',-Y]j!/p2L%UJต1_|mC:0d[ĉ쏆[Ý{{76wn HU>x$)6Ot'GևGt%\Vv{fO|cOf/npP~7jW̑˧>xf7~pqn[.2~vI?vܠ4ZwHIwKLa*IRf:'. 75IgIb6d"g~e9|ɓ|wޕpJ"L:AY-< ,_{eIևӋN  `kOl_= D K0H%!NawxBB-erVZK__EH7%&#lC€/^C0kc ^ yHY=zijGɴC8*( J8:t=.g8@cQB~/,>rs4!s3xo=+>X@hx#MS<=Xb0=2ÿva@%+EP`Gr"\c y%Y`}Uxo7ɴa&ؚ}|(TV$CaXw,fsC1d\v*xf̢~Ԑ(C]1dA&`c9BzaxδjF⌑f aLtrM=BHĿibE{ r6x]<$p!ݓlV$ԩe?ZBbxԖ pgV sCg-Qxq!T gA9v\V"ů‡,QZ$L@cP/Z:*5yyuGNB ڰusSvb@/mi(lgލmQlpD\DLlmr 5m.Y+G\<T "Vq<=xli$~;/  A?~_)xfi|}ˁsED+ENiP6j?vZUGLƠ"Ps~ (Iibs0ZyᎶAo/ a"Yk!!qx\HZw){NGP+ @Q7#QvA 4*Tma[|W~tX!Ӥ=+x怤@ c5jfc'9!rÙ;i!GM倘{Z8!c J'IVi>Yv 66'{'MI`qFL]@p!EJְ1 )˪Sui՞zSo2[?ׅ adtxRX?94DrG0 `Q@O!dI6G-jZESp%h@s;Q /xDׅ%t4ܖH/k6$[2Iqnrp%3Rnt!>zg6@ u353a$Ҕ@(a)TNNW踎1Q ƢSX[ F 2? ࡂcl6(m2E\lj0P@hsSr[!Hrg'XL̊xK.JFN/xs0"asN!5o7*c6hʺmK!Ȑn#@;ߐm8`HE\18~'d/2QLDaQ鍗=~g_,gJ(Fbem cS?6;fkز/W.¸fZqS /\y|J{b)k0Eo/x&꺷P(;1W]Y$l&޿5;ő=fg\momUWz+b]bqm~>8B"(%V{j@>b`c*'ˁH|l]Y̙+UG]Սnu6v;zu|jqW_}uN-MM?Gl8?^Uilq-YDk` Yt@<$1NQ=h$3Tpu┥0MV:D`W_m LR{Zs~pU:ksAywtyrC0%acA Q5Sl|"(nV' P)CFWjDQ`=tn=#ݧV8v?wOh˞78]ڸ}}\؉czmsx'Obj`ͲI!(=aE*J# m?k.+j8>&YqߟV7,hS>qEV`v_R/>6^s~GM0pu ŀbifM],I&DHGNqל?]L]'٦8?ܗdLEYi ǹIS^|׺7;?_},swȨJT`v.)O,vNѝ86[Z ;vjŖ>a۱͵9to1Ri#$*5h=ܫk~DU7ޤ]Ej5rϟ?ړO}7Лg:2D[L˞SjOՅX]w!L^1RIkdxAdLMsSX.Y%Le7(~j<4 "r~"}+K_`s+_׵8??=-)~G{Syx{wcc;(zsoꗟg~6{ΰ|NXȫ@}D8T!H4t?ck?:7w7)-(c[Htaief UҼrX߃ѥÝLut1XO=_(-N']k͇Kh&#gZ(@j<`(#V9y2 m9M%&NvZwo^_/G^u~ua䚲FjZ7kYE(S̜>[Yڿ}v v: 'Vz3#S|T9&1/l+ԱT,KuŠpLR WI¶Q_R'Ur$o˳./~*}׉N,=}ʺZjRт/iFt{{N8w2EvOMn.\)N.Bä$19g\R)Ӿ\ݧwuaKgkWpjB q|1fBj>^{꘳ ͂ Jf\-BENlH :R GcNT2w|`n/zgFcTߤ0RR&'a!4s@ITJJ#&Hy_6BZ#f ,e XA}5}|nΥj*^xT-.̜YU4[EC5MBɜ^33PϪ^X|/ݙg;TF;_yZ_*^޾E)E4_rYKڀ`# ΎX &J1ΰZ`@kx2"% jso SsssǕGv'Uu퍢 sye_ ww7OntOt'wog9_;rps~_z^)X. 75q̢1KAK"Td`s 0>HઘhDzm52L)A(:v^\.pƗ2pҿq/4oN5N,S8ipla0UO> ]E[_~&9{˫{í ~ߦ.'T77%tPC=AR9< u\j "{U,” t: Du5Fk_+Pk& *,:ʉ=`cW/.NPb2ݥ0%w{dWvU/cXZDRxiRrRƴZLͫܦET{I ԓ(5Ii/N"ӊzyBd3Q)ag7~fg'^k}pІ/^~“l9wc{;'5 ?:U蕝ݓnݷŕ`*51v!j!␴&@_! Q>p/g'@L)S! cJj"[ ;{ގf&Vݚ j\}+yi[vZqMV\SkX}P~959b`Ѻϟyy 3Ģ_o_%`g@ԣR)׀O J.G]I !qwVXfa;VMA++~PG,E>9X;:{G>ph;+8}lw8Uggaa֌F0vF|-+~ՙw~Y.[ꑡw %:Fy!92"b[IU3YE%y&5ѯoq8 ^U}pY=JkzzF޺3;߃#.v0ںz]ɘ Z]YMЕ:P#Dga83s;t-38PvizUwCj_x4Dy ;_>5C֍G"ڝS:BE+?封?]y~M=w3JR`fnن 4Ãխ~O6uɄLw[wW^{#NyoWw47f(A"d"nMe_2Xlki L还yYڴSɡεr]a㝑iݺ4售uC3wv6֣C6ļ`oM(PMFfom~o\'V]^WeSJ;)JU j0  ARRKE\_ vZc;2YӍ WZ:%ζBC Xv=#{j\Ղ[W hVۄ?R`^mzhwou^SMP6'dZت=P7OY^!yq aot'H@sA-1EW)|FMD'JIPپUnj7D}.4ҹooý\)C4kw{e&&W)/A+ ăQCaRb\1Ҋ QZ 4PZGҹߝeO|͹# 76jgO#!nX[h.C/- ޶ pW0!k6,4"*hdy%5ƙ^ #>[wmQ㤇ViʫXS׵MӌCw;:LX^F8Ο\,ݾE ؎j2t]dD+L(yŁ4jT@O˅D`B`ipBOJD9G%O`qn_ڝ3h {O6 ?CmzǗ`wY"TJ~;ܫgƲdss7_檅4:5=nn&Zɀdue*Qߛnyz.[/I%*P'!O~"8#ޛP|CgWW/=r:9̱չNJʔ]5: }KoίJ.mv.^TgG8~}6DS>X@MQ#_ZtZb٘qfK(X\ͽf{[/.!=wt&^: _pIXu%|d~2q\/cnu?Nm#do ؟~gn517FeL1zv$2"El $nU IB0Q-KF6]q, Qen?PW;>NΎ;XSs[̯.<]ת[V''o}G`kbuǛvN)@PHHzĘ@ 5>; @&h$:on)ΞVCYڿ>8sn93?{}u^S̓Uá]wyQ}jR`o޺-l#VdM5hH)s>wgmUeqj8ڵ@5&uW vpZ }NTWnV*TG?|RSDInL!:@#>5$Y32nhj7/T}w:1o{w^\\Xl[݃.[_]![&bO,*W*&`^`7. h/tu'>2`xNnG&XKX4̡$ސY*5V+kMc֩[4uJFfj =4 ;]WՕKA-.{_N,;YUB%P!ÛwcG,ٸxogQ~IG8E ݼS AX2"DCcCȭJE))N_Sz#,(=nbN :&&'X]-/{Vo0TnBѕS 80հ{Xhڙ޼3琙o/=G0y._ >P՘ΜN$zhК/&"!<Rx5֠nl׺*5L0&sfE+Nbr~|Fo0AA0pg4y|\Bz Ñu/m/[?v򪪪k]HJ륵j]lI)J1L&I(*f^P$M%ɓT %NFv+<2+V?_}QE {;b箺~eSv{ ǓШ-`7Z~B~EC]^f%֍;~DxEt Csͫ1RP3'ZUo|M_GVor/\\PVhdwHo)kQ SmlV_}ARk?-΃P "<[`r}i((b9Ez|dyYɡb҄Yuv6RJs We^Zh~Oke`'6DAePRG3&j`{~}u;/@d8quKu#˰B>Tbz&ef]]\_J[kZ}`GX=2rpƎ3;f$|LK*փi"VnV_iBթX ؠ,rhslu@I`b$z؄ƶ=|Dވ~s03NY l<~_2n];;26 )6WZ|^] Ne!t ;!6ьjRT4)$/a,SHBDA}#۪"9[Gm\BRow*UEM(=T]~lO8 'XH\bG)?kt]vj0X8TM+s^uVuvleĀx95=[ՀGM|JGSU|B ^5hCZtI)sCݹiVq KQȺN 2׫wQVtQ7f0F3jFuF} E"w eyH+TYaP)ITMk6NfTRJ=X7eYe[Uh&3.nml^!KJe!Zd%J~Lm 1׈`()xnD)]␋>H$@O:3y;ZiҲ_dL^RL⯬,}dǦY$kњ s$oBN&e"1ᐪfm,b ݸjlEbpJ m{QB`Zjw4 +V,$dJ0 S> W^%٘' > ۂI`g' xq z!&SQ cj2G|:ЦC1JA T;IoQ>2Qh0{HXD U<! BCH{\&%+d<`f/,Pha% Y )[g핽h|%·r_TZP&!IjV~|W$ UK" V:u,`B4h7Lmu˪ƔdK1+ 0P Gc7qq5%ג(S0:tc^{_n\zS*L`؄7k^8-J.}ZȂ(I9a",PҚ7:$Iڹ ' yh`t_@%kcO%4fڝ{UXQ 'k#6xǴ #$'l3&w7t$yB[_`A83ÍYKiɏgH{ҐDžE~֏4tT*]d wS+2&g _dB,IǛtTy{0ZegJnqz^73͍W ,tU4Yfɡ{f9[oʱe*,-!5ĵ1cR=ĬYcDVtlbI s`=r"Z[ LPrm4)&w#Q{e;_@[JmF܄<*loBd .10vԁ`ſ4!4RԂEA=4|r ૭U9IшEqX*ۢ=jܟ]d21Ͱx l,Mú*G) k  J AG/ %0r'Óf7{߅wI(# M1x47|3_q7z1%j/-ztY:dTZZ, hϤJw6!/3cvr T$%-koؖN׭%9a :2fAET8+Nם~I+5#o!kf jjiǧR+`!C싅ЈR `y(s=π98{+=&~cj7{]xOk\0^АPT|[iY}roLY[Z)իCZ| X u~ p%#+ |}ι*+w^`9J`!&Nj1 .Ta)/ vJwK}k|w0u~rgPJ0h0r=r:Ι9؋NhMdwhU,_8zj :>x2QU%Nu)kDMP1UeFV6/Az.#&WGHM}!+VI紹edo,F qu5 !mZJ?S^:Sz8^?Y>> x@=qF}ˉP·#!K%~qngw0@Nu-Bv`lW䝛/W)8Zh4!QS*QG0 otI YU3|wiaevz aX*m ~c41uo=SD&@UM%@R_AA ys/[(<{aղP=xDY&ߴ`Ĵ ƅw/dE5D^T>A$q[L,#F>F2`2 U-%4vƮu J$ِ}(cG֘ C[ 0 F|f}8 580>M+htVzޫBEOhc-Iv"yC̋"JZ[rupOf8I! 0⢰/`蒔$sٮ҆w#ByڐaOvLc6bW f(ǓՃ4Ã+;މ{k; [,yP/'N_~Bg0$($-eui[Ύֱ~248o=eaqtNa#VR8"=S裉 b_ v 8y4H0<bZbJމqR D`OrTEYxT<>*ƕ!Ѯڠ\0[Q`E_ճ A\ ͣKuuC;T)'C: P_UŒTCLG-kL"v )hjJeQR4 Rp J*;Q1AjH;yېVR-dQe>ZA#PQA-FXV,JҨRUՙ@-_fLg qV+ "4CqHb鐀,^D2PbC$nᤪ&O@},Kг-ؐٞa}}Aɗ~O=N&5d5+mY*4b} !4r9Ʀ!u1mA-*oљgōc}`6P3.q1{hM;#3ɎZ|YUqa:j=y8S 5=@P? (3#7dvT 2IwPm ''}%Ԑ>d4r$r^Rth̛x8xٚ;P.xo}K|vM#M!8o$GeD TKAiQd)@Pq+*xd~ DAmcѭMCN%Hͺ^DoPq8*@[W_\jk )|*ߋۺ"R]tbjfX_ŐA$T}K)4UCEo o S"Cahˀگ^ a]V9!pz -Fe\ў_~pDi,™Hڝٮ3I6TEU |SNs)nT~HeЅIceMy%Sk#DR:q` Q8#;F bVMw0H΁2rK-&BdcJkWE-|!sm@c "L m`9HuSe J@UϋmLDDaZTPG4 hXZ(i*awJe[HZ4Hj`2+t]PU+g ~q|)b5]"[ G#UեO ߑ4¸r~|$((gԸNe41RL\a !XIC1"TIP9D=cdxubFi4t(0J+BK~+v|j` __+ܑ3" B&Y&2A+]&8٘#OtHT" Hq vjZg8S |Ȃ6JN&"xd 8P,!k,|1OCldC-K֡ !.fcr<z$@vD*a9VW8qw XUIDATx ygves@P`1Iġ U2NŮ8L 1& )Gep D\mrB+@HV1;=^=jW==Gj陞_cei$C f`$/gўfwR=s@X طimҮKۑ²4IӤ7iiBHV ÐI fiթA }ؑgWIt.G[jx&\SE-#t|RZ:Aeg$ZHzINzKiRY&óF畐R(NF.dtԚ.;P6M;@;!9=rw$^_E{1m/i)p]ĢQ)'9PKEV*$y__jrm,ױ۽N.swxW7ccа;66xNqLCiv&eZ$ؤkK-Y1M)ʝ_^Da|V۫X{8;v/R}斗?+K3V.=kn.2-5lLVȟ|Rc2k27@=E;m#zo7=äH 陵ԥ2wQo+D)mPiJB9^)084ÏV{j Z2|92\<VS_wk2ȹ.zz[zCϯ<]P/&;_gny70}0 x0Dx63brtU ^{}7.euI8`P\5wEO-]<%_b2c <kR_X?X(/le_>=os.j睭\xJe(r,pO?wq+(Ue;2s_vyۑcb.ݗABcы|4rT*!9_{YS_8 H* {k 2'xݽ'5^ûdW@ϠzC;{WSc\+TpFB)8NJH핧~A]m i}f ^UX1ގ1wC?#)0< MUu D 0FR;Y*Wb;C?8P/z]e9:WiBUg!ι{A{T!k5sH~cF эu({Ņ92 ́ȹ.%G"y>M(״*,HTYAiګ)=b$N [Z͐R$'W0:*eTO 7#) $A-^ibՕ+VqyͿirRQ"%  鎍})|X[./BaYE+ ^Cm_SaLYtt`~m\7^~5`̰ZwB q]E!hXzptǝ!ǂBm\Θ@!h´4_y=_uwǣ WB:q5 R= t=9ef%7 " ٱ3 xVPHP,OJ%LU\r?ÁBdu;$.qQ=\RHwhHyQH0DwH@C(K*V;~<B7C<ٙZϯBwM[ z6 VKwtĺgubjC,غ˦E!]Occm3k!tt=W ׫ֹPH#<@& #E t)D掌 (t]N$nb"n PHixךP@B:#H-󎂤'=v8e.lN2VHcqEe ںȭL'fh QH9(Օ+.Vd[C-V! 錓N,ܸ>"V(d#<'^L')B0t>O 7_:L-I'E'FR0tu' H7H]C1_+5p,ê D-@3rƱ}ܺ{ʰA(%^\A:Pz@Ig (n"'+2.*ܸ8DL-z“W]qY+h, @uGUXK/a}%y϶<RH 8H !H $'^\/u酛7;CIUA6p-}p>p>CCCy2  ^TZ\` iݾ[078<ayb6  YCm<Hz{~)5@pl~܁C$,;pC$ YYimOmͪ[t /G6nE 7VxOcˡ.~HL+k׾{U5חgMW)XgkȨym~6׳G]Y(B]\joe+=hrW86NAO+ kogaySb!30:[(ghvM'yS+`,ϓk&=FAf5bl=m?Zr`b1) "y\[}l2!MTOV qw<@!PDw 7ٿUkvyV*mb(3Mmj~B|'l0 ?yb`LMrz]A4#v sϷj WC7ir*e~-̌zavz7B(g 0C@T3~iiB:ٟw R'@o_ZyKa$J 2^!@W]ZH\N+ΡNqÿ ̽t4nOH Axtrds.lNAdN*͏$̃z^kH FGEκ9@6׆`h xtZm7l,c AT!ص BN|)< 23o{EmA +bxX:N?1e"TXAK|B:Y*S. 4*OP **"VK|Kp={ M(=@j=~4Y} 'P90tWV9jn6( ZPH'y>OaW\z2S?ã!>"h \X8N.ɿ?Gi*+Ep۴=1}ῊPH}`U1c3+-EhpH80oQKswB_{%r4 !w#GP_.t u'\ &P!f_-]!e ©vMlh!td(ʰZ-ĢϜ?y rkRV(U#@fpTj `t~DsED1i(DtRJ٣8{ڶhw5 W0K!3N"7m^q <'QHu\=ێ~h>K\itg,ѕFcxK/U*㶔zP:L;"뭕4=S.ڎ3ku+uT@D?VtG٣ԣ,x@?pԮQQ)_կ8-xJ6J}%yjӮ#a,ePD>뺢V-Ԟ0qO,̊8/S ]y#Z3A:>yʫDKsݬ爂yA;}O~$cN˞9*pwˌ+M 0{_xE." ?;i_dfs>f1N?X*|z iW8$40FKTvS-5)C^{Zicby)Itm{|ap-ar/_S9K%WEIֳv10,5miv75^(|Kftby#',4u]LH lQs#{STmAT&a@h_Ч)aR-Sڐͷ+ٌfL93lr=-\vk[l~_?RY wg/Tc||lr9ݓtJ֠kDSi*Xۂvu!uJPb-jUQ3EVRҴԆm}X-i[KR{΂9D,v/KŨdo&T1U5 WuuUW7YuꅔZCҌ>@/V S^zչ8PwJ}RickmԦV}FtDKȰh[ٌJEʰ&+hl" U@FF,U ])SCk<)le9y}󝾜ِ3VH{U>~]m!Y3-$=! uTiIENDB`admin/assets/img/cff-icon.png000064400000000737150515074560012123 0ustar00PNG  IHDRJJ+2CPLTE9V/N4Rh~Oh-L5Su}1OFa6Tax8UC_'GӃpJfߺ٢̛Ȕďy[sٵ֪ljRke" IDATXIo0aCSb}+JQC sã`8b~3w0 vra8_,W`LOPx H@E!PQ*%dMFa'YʅS3LpFeιI1<AɧNzјڲȡ ۴Dr;i;RX־^>IFg2jԐQkMF!u[i_Jm޹U>Fx[ֻ Ḷ>b)NIENDB`admin/assets/img/sbi-icon.png000064400000012055150515074560012136 0ustar00PNG  IHDRTT tEXtSoftwareAdobe ImageReadyqe<(iTXtXML:com.adobe.xmp EeIDATx ty#fb ODT0@~s1ۆc@,#bnF M®/6#sG/.)]vuo}29*пQiC6 {^^URs-$jHFt-~7rNT%9^ EGW"D֭Q N ,5<;c|b)"?N9>KVZ ?-2cxN\T94_WR'R':OV4lZo|B2L[zu'|Avs3X1>ǎ|!t$iCc' o~Q4sN%cIsPrWlKG Qn.2w^R?Td1>rq$Zؔ"BG}Z| .vpY%eղ$P9+,`D (kӵdWdִ I2<׊ _3BQusCU8=]mӞ~w̎+Ϝ%-X{@X#!6 wᑳxTzӛdk[_S ]a՗wnQ LӸp_c̈Uy/2X$'0<#A+L^֏:6y= W&OֶqNʼy5Oq K纔t; Ó4@Y¹M'!β$AR :?rqIq%E zJJN\G8T]??  ?"J7[}[_:p:^8 jH{ P4h:/W{6! ɔE=ز\zRqzB5f:\<剰 P."Ou0'w Ahufo'j`%zHCM.}θݐmT7s{7œ9H~)3"? [E//z{슶'|_vPr ȩ U~=xҌV g`x1;:Q ?Hvdx3}Θ^ۜn_ z)e9>PS798g*GoNJynY:bc4% ں~:vzUOmsx=2O67#4't=8 WS;Ol]HlpY0 I/j&+lïLK=;Q[ ДUq:-m1Y4̏vo jزv.M,f~Pl udQTxܳ(q}Wf• |dَ>jkA ۔FxW_d&PȏЀBdY~g?'սvnrv ;c9iݩ3͚pHgm_zU`Hۇ8DZrXlr M_;c--WH{`]S{R;{<扣9pyx9kЯ( ?#=@ E<z\nuXQyQKvH9g[pToy8I`j+E_S~ z!#ީ7S͜(GR _>Mu :@8z{QC o1)i#11fhI#If G>6SsVi"߸wp |rt</ҩdՎҥ2eVE ް8zGoiq_<7f=Dq x_??7mV*XļWOnƲ-/i8T_?dkc"Ulİoʒ]L_1~ûpn$](fP}[%0gOVn v㷙qD;3Ia0[8|/߮ `YhIENDB`admin/assets/img/rocket-icon.png000064400000002132150515074560012643 0ustar00PNG  IHDRpp>y{PLTEOyHn8c*˷Yd*bqp\tRNS` @ϟP0PPPjwIDATh͛r0E%ٖ1K6kp*0ܒ-U[r[bT:O $Kቩ&x$WضtN(1\q%`| ֩ jWItPnAJ @@񈨰Nܟ0قc$<_5ˆ|dd 9r~,~1JxBq<2E}Wp½Iu *L@bF5A(ƘЬ1fW=eCgЃVkVC. )?a/(aCzBmդm J%̉#c*Tg?zIČt_m lͭڕ9QM_ј` 3F:!!lRag^p՚6 64},˄[zBXOlz۠\=V$ \Yؔ#l_ -UM;-wjruաjر8|IsNG1 ,n Iv̸gje9/kX3:V`C[>Nsk}@cnN4GH>~[ D#eg%r18Bini 8Q–8ׅAX+@ M, Q)`F=[ .$<")`cQgt6/f|GcdE|d #ȨEN"@CARaM!' PWICD,bGROhQߧ:# Y˅Γ2ɵZwb0,IENDB`admin/assets/img/rocket-icon.svg000064400000002042150515074560012656 0ustar00 admin/assets/img/save-plus-icon.svg000064400000001233150515074560013307 0ustar00 admin/assets/img/social-wall-graphic.png000064400000047462150515074560014267 0ustar00PNG  IHDRp(<PLTE({:Av.5|@H!-ؙMU?9}ف^28zҬ5N#(Pa[c qP.\m^m*Bo_tfRCrmQ4^QTo6u=Ty QsG=x׃,.9A.@3ٶ|iaɖ`ߖbmGwlYuTF({WS:lxqDN6Q=K$IDATxܝKh$U34,]q,f=Nn\U 5Hv!$;< t_>d|ߢWsnU?RU֭4|{Ni"xFz{{olU R:>>.Wv!~P'FxdrD5oxϯxbn9_^i)qƍb6~?&h2H{MA}y;)h<͛E%r4Y8bG:Eބ=^:z]ˁ;C.̏pNprTֿ !p#9{*āNfYBG+p?Q9]0 wNn±pQ/tLJe9:g*KK鬊pdf-OK;*&qppM:MX_ފ`o8p q*SͻXלu+(ވg> NZjMECWP/ޚftoLgAҜ $2ȩ֤Iئǁ*h:_SLtEQ.ΖjrcnfpJDF.֤ug+mp,I5yqcq\i:c5)epze4ޠ59L0֤kY+opMvN*: Zk!p[:t&[:p7$P'uqu6PK;֤ $bA34t WbtYm̀]KU,ݜ3.ȩ$rpFgٴ7]J$QҥpNJkĬ '[QSR*|o 遣ьJIո 2cp:slb#Xk|<ËaFI ZrtJ;(tVg'˕t9<.M7rn,!o0 X&Qlt&^:td6LLr5* a5dyUteBF&"B0|䆧 w}WH)R'WD9`FhMگOImMLV#NCač\O'HpI'k`u.pK_Ȧ == IZ:0ҕc]S= pqCx;ښB r5)=ɂk|PKkR36MkjAp'!SZjTkR8kTdSB"8wVt,%3j`EQu^x0ia-]Awgip¿jJĠk5Kd[Si2.mq$ e0BiN_N;m rzkRXQl#ϒ%ptW/_j53n*Ԉ?CS.Newفݚg[S@$5)lk#8YEDe%PD Ŗ8SՋ[ xS8&zҭZlU5)G) )M <[UJCkk*[yûre&`0m%b &Bv>ښ9}Hp$ ʧ2Ze΃7ok%ښJL&#R*\;%bi* l0.kLSni[QNԵ2٨'pI<܂OI$޸˂T|Rqg%QHra[Sҵ'ok X*HȦX b9w]keP[SP5݄^)O/^da(I/t?ptښppQ%jh0ky&U[HI`mMp7om<¹b,"Gd͊ni.˲I6Z";{.?F^uj`pyIZ:Œf "qOI8j`] w V pAs$Sn -!l\5(J4RˢfCNAhpA|OkM :pJc׎oD7QjkjӆIqy2Yu^t2siMke$C",s-u-ִy5(Sz[Hv/gk68m_֤hAEl iK.jL8o50 F8loa.=Q&d"?pdW&A[5 " o1^ b_e,enf2z|mK qN  BswÓIy8)kPnQSZkOJBlk*ޱlU9teB5Uu 1Hk`oo GElkZVqnP7qRbģ5׊FnN݀JM:k`jk*inݑR?çV69rWi]Q< X 1W!ᬍ\7q 焮^[ |H?Icu-A[8 p-^K.IHNokZY~ N#-QJO֤q84tIX:-I[ p?m ay,QQgɮuۚN'xC!$jҊdZi[55* 9@BStx6puՊpH\.ǿ{Вd׵87ktHXu# ЁӅ-xOAN&QQMI*ҤꆞK[gc #"[HW}Wxf&g&KmFN@55 06< YUt2*QH c*Qvjk:&ub|T+}ҶIok*"u08Ο?m-Q. @#vKtMMMNv RGSRWhosnAM5Br\\8aLmMԚRc 6;q.R*wZϝ]ڔJKDfk%j?s\`fN9i2fGU8b.rwp*pLKwEkjtTFc18rx `S upۚDkR445j(G dU>,'14!rDML\GXښ0 >pdn*MKR0rJ3'J*3 8Xk7$t)E.DQN@F0:\2}cIqj ?fp5%sC3GNhȪs厂HKd>$j`KV%Mt bmM+ZE#k89n9e&G 8%֚pWώ>*&ʮh( FǙӤqQtm𔪀#wd䔮ҔY,u.8cyښ DJş+r5XAFzRYLVhɔٵ]} ,ݽBpmMAҭ"4tTg׋'957`t뉭7̵to8x][߄aV:^b.8>t'ȧ04A1愆hjS~6 t;6&}[[ Y:/OkjG8k[R?R5B YӡT^*t%mT,FۚjA@̊ )u@ESr9'm4`3nlZ밦6Lt"ڟ9\F]ItyRTe Q8Jcl~魅ͩ7<8pon,6 tqT=b4nNƒKP6$CcBySj`y+h4KmM96=`U 7+o0lR RMKpqѕgt加n:ݒ , ykMt$'l@.r 5m'wvzN6@)=t' os,lmM6,;&,ȩ3# 7ZrCs3!!ȬZlf1aZQ.L=z&X:4t]&.E~7JBqS]yܭ1hk Vz}oje 5ٖ<ƅ' \__&ɿ=N]`d֭Pj`Yn[/,§7vn$-AH'K) s `NwtځZ|pj`<n1.p=!xs7ًIs홼9ݡ{+v^2 hkz=8+0!p5ɇhkKZ:Św&6RO U3C[00ȁ`5>N7^If EVGB#IdY쳜&׷tt9&`Η_|9ҝ,]q8Y׺ ۚ?~ suj[p8ck :8%j"z;aNo5ɇlkz뇤_vb]9h裩&hpD^juV+t 3y(M\x{)zښwƁ8%՚Cv?T߇(^ ZV#z6Z>6J? AW~Ъ]y7"fj`%pܟY_a#@cBˆ\877MTm߶LߠĐ#G>KmۀI>`[oj[&~ .W4cIa&]B䒁 M1<NV9"`[ӿ"Y"ݿ[!ܬ\sSf.9 O ͊ [ym8٥zmM7ǭhM H>_S,G8ՙHo 7`rHrSlnZR}g"`p-٢WKěNrCA\^0uBЅ E +A`pTB m RO A" > lSHE>WZU9wnNfL2ܛQt#?s=Ld3[/jfs7pu|mY`w Ҵ JRBCZj s-{&n`nSHxK$TzeqۖO]ڶ դ썕&'k-~ x#v M"Y5T" G 8D_67eo:q2@/npKW. nhcRpTWt#vaE][O4 쓪3mZj^$v\E}pJA_[VRK1lJ6%T*蝻o3Ѽt8iq`p QG4 }YǼ>t&qӵ̅2č*jL30h!v҆02W ˫ġ\ k⾍-n䍁C֘x{_՜x*e`o.D8ϵ"0#j J^ (GI-7ߊZ:[L8Jl }mYŚvpǍ.~I8Dj3:\ЁpuBܔvhRk lޑs4zY8kҾVRe[4&-R$p.R fT2 p ޔ~E'{5C2pXPqc1pL c xR  NUW5Lf 3jMՎ5{pp+U&M\@ 8+*xTJytѡd&+S.I-Я.p~T `ܘ9688ǚϩZv2Lw8 f`ReW[[bMcWY_RA dvı|3N.Kҍ>t㽕z\U;s-6 ["\x㹖yqK7GR4IoCGO,) yHMt *$WEm'YU@u ІhZu[!dkG eip44DZ+Ɍ&Gg`<ע/P}:+ݖJCplF?ű+HbUL8o +헼\@sj nx [$ g9aQz)-r̙<]Ҽ.pn֚kk%U)WT#mXO#ufk[:n#V]"@1͙BI .o'}l| h$ge wwCa]<냖m#X2dzz2JåV&5&4zñI˷{ -mgזQ<30l@( ç%\yDOJ/Rgnpz%Cv@M_k:|*S1v5D$mxC˙}hqqop DξAѥד¢pa#Ûyg=ĒyѤGv&!p@[ʛ#N&Z`pזґS18 Np8Ѥ +M"TmvBG~q G{耳O-lIP;\# X/("8呢E׮߾ c?.naN('@h~e8MZb17_,:q-NvnhQ#ѽ.7K;8ܯRySp$OIzר=~ kgdܭWU8&YTg*Ja­Oh&\[ѡxc¿`dMr唄<+d{w-nvS[>2}-M]0f t"Ǻ *x"0"".`WUmuutOw=~ӎxz_MJ8I7M5%7F! Jzӗo?p4T*p-ܛNM !9A@ dRLNۆG[~bZ_^݀y4 =N8>ѤepBx0.kXOH$7Bwף-qZq gMl;4p8 YexCo+-ي]ϗhs-o˺uLBnѤ_hRA6VʡͲoX 1ÖdCM/_M&#iQL5с B4IZ8ԘF"e6ׂ`:@yշz- Iw' 6'$mW$a =Sz=whRFzo$]DsMl~Ѥ !;tRp&e&{Q$M-p}l{r \{T87gvx%Y08IsK\9]i zrcFK8[-\yzo"I`7$Ӗ|-YM}4 .Q링0ZƸAvjҞ[yhnΉM Wc@T4Zp!&.VRb\ێhDl%t޼= jEA..qz8fq;/Ik7:(-7{Zz˽^5dM[uzMb+'A@T3\`"7 [3T:!y&qWj 7VU4Z 3 0Roj#'Ѥz-ܨ⭨8zM4 gT5o zsiMb"H޾}W=]U4_R8T#6 mۢEsMBhP%}}M{:MLn HKZRmiâ Mۘk1o, A:6< W8 g2|ld8x5ת8RyNnK~QhRT wo8ȣжz-tDEDS.R.⚖ ܈7|GZA$.@tt,]g`4*i G. =pTpHFrhM*y(qA &yt*D<z.w8:̿2pMjg pCD]YY:=o͵fo^:8 o3쨃;zur?P(@r"K &y@%=~oK)7-dr[Z%2gV.Kj|4˃SѤ*3l\8 kJ}3J-tùVclZ*ugk$T6ne]f]5eh nK[F ~~Bb LmJrX)3TM?5-"T4moϷ\ZQQ!hSلH,I3:8;dj[tG'[B`QĶp_m h~f`w8:FU8CDߝ6dQP"7ZQjewuM*IJm[5Qct406;&}*x#uGݐt[4f Z3ЃsM*YG'>tM/v`d3:DVɛC)$M.ha ?mT|jm*']GWvd=-^mvphI7BoNE&,`鞦 hiRbF6*dF ZѷMDf$Ś!4{&0qT䢌[÷Y/ pY:$Q[[5J}|9T: Q ѤժM nfoTb xllY:&qtXatp~m2fqkvn 5qi>-l.qqB]51AE蒥 zsgε?N?t4RMVR:#ƚM➪TTgo(poa.%e4IY8jR>&juaF$!ࠓvgkB4 Ώ\0f\ܴMWp,hRɧҡ:A٪`ȶ bMzpvqvjpaXXv4Tb-i ۸]ЅZU-;Y:30}<ƭc diPI'ab3g04{-BѤLezM*ZrްaF8w#67_RXp',ITۤoѤrǚzMpU30q" GMjΧ5[8.4g 9\+떮7ѤRx*aՁ08.N(6=Kk%5hҙӲHpTToIzM\.JDe*ڰa2i"G_}2pQ®U똁%5@7@ CopѤ[nϵ6WۀC4 꼥N0"@}4n$tr$ -E7[8ĚbI8930՟^rgqNj{=oH=pl gnT¥oA/?AMTua4s|cM&9s3Tɓn#=c߲ Ѥ6JF4)BL&-Z_5!K*sFRh+~5SMp&eJvS!}\9NAZ̍%6Mgq9B؀޴xr]M.x徽Ѥ[%cp#GZDKh ZU58\#\ ˳Ѥ6+4bt!ִ*LQ=⎆csrjZ\&DL3 -;v{~&t56VJ[lo`ml*)[ kOQ@I1h ȍrZ\S u4cF, u7M$W [c?'-hR-;[͍X_KRôBsS`n[:3$s-NTd7$]7(_K]hi@ VL*Zӊ7 WI}@-]xOnQU[TXkYZ[E.z݀Lbuno&pJאwAK n)^CEuD0uv; K몕#܀"ѩGC^_{/j@X\_s.1o8jQ]grA4iq{MxsDoҶt.=5t =ɤ=)?I'0-=.q-ian-MϱŁ7zH_Et39r_"j[Cu5r8F.FnZ:Ԝƙ'A cJ'JjPO!)7+d/ ^/'o .ܥ%I 9\Sfgi7ww"H ʞ8)Z87hrAp>ڼ%,V38ঀ\XO?Ck0$4 ^OhӼiɽ,ߗ_~en֖.?&8Mډn'Cҝ_b&I`qJO<G~%p,z oM˰8b7|E&.&hYI5ݢj9`pO3ƍ??$j.LǏq s(ĉeGuIEkpF+jHK>)br8 z84 g%/Gd4np8F:8y8k+?*t@nA]{ICG28U@>8uClMֈ5$N Ts8%zmuݞMphV,pK7 5qK8R=˳=rՔ;qS_ՋFsC4+j^n -@ǓT8!A[8 n Ih0y;qCI4lV:\g@c+Ńaf Dz [:(5#挢̍8wgoLw 86PSrKg?0:X w+I =bMC'g%jq$XOQ}{ݐl[hDh"{U1'&' IpI]: o5-d s.N@5awwD5[@6oX:J +ԋ DƊ Mu`q"QS{Ku~\_Xo!@}@۫ߦEۻ RQKRcMkץNqV)TT5sɚNf34qЕ/.~KCFs3qŜ^| is#Avȕknm68%^ן_zuM*@\hREC!tjaIp(X5lW E4׸vGS'Z5eor& hR=/"1u,3&%8˷ev@yW3ۛ{8Y4E˙t!T,rJ#[΋_jvc⢋jSI Ccؐ ǵ}Uud8[5meȽ,]T-6H"\e!cފi-:5X\eseFX InPYmo&_ #ı&{{MyvZoO6b,E{9Z8x'xPe!6r]ܱD&@`pL\-.o޼]fϝ2T];fmX15\gJEZ:g9)? k3ք w4x; IVwl"}iݾySyM? 6\.IL8ۢzT.ܹr7(h~t6-&k*nQ&86Nj}vumɀK)Ş4?Ïˌtqn)U,GRK׺pS+T7cMiZ )xRnߊ;wn*ݹdcqq3* =B jx_uAΉ :yt_/V66vnlm?7%nq>.QFsF9 u{˯k!7&ȵkə$č.;esS$D1^\ݽ w<ߤn3ܠ|̉L*jŚ~DpNB77Ue4 nѤ,$7(_"6u/XS \CWWN!v8w&:M|VagZt0[]4!XP|ƢbMF4 c-ϵ_6@tEea`ZG CJ>2;љrWTcc|;rEC%؉&pH pGQ:xCMm:\8pZeC{:~e(I 30nư<Ѩ:tHCGOI8丱DLNZ* gX1*牷G"\n27[^ ʘ =N hk]g/WU 7{kv)Z'87pJInom(C+Jv[SO -BɪPRMZ69*tkBT"NST ޲'J;폖؆\Brcgk5hZ@jn )p,&SoڔMI{W:IvNCŚэE@ B5տ(`@*,0%ީ* '֚YŭbO ܱ+-D@!4T:9+!YbM+6 -f8z{kh(%s +݋%Q҉8,V] g`2"c7s-)^S UT5ר'Fau' E!m#0oiB--]7,q4p&qG1ݭ`Jȝp͵kquX#G\#ĉT:H&%uX֨hRD߫'Z\Jp5BljWXԐ־O;OtTOy~phҎ,z]'RT%H'"ެsZұHY\ &I )ioGbyr}Ks|kpM9QpCXkҏ"ĉQK4SdvjQ8)icd[C&5ʒoe_3q|E/Rq8zdkr#55ujN?1-Q~n5aVuZ:jpG~6ig ('XhN"3ŢHijZa(8g&KKZ .bgu[HCn Z^>k*j)4F͎RERQ}npΧFgdFNl뎐Z[7bcM8,N* 7gOaR99;bEG >yphF>nƚ 0p}Z8Iu ]3Dat!E7n(R88BhW`roi5yr\sY\|3;4l>g&sKxɛcX$.&ԨnU@5O|\bjH |l8g`j|JRQM tK p.. yV;D:T`Ù!#t^&oT 7Bjfh#LYREh׵yuκfm >亥0N#7o8c_48^久 KlE5+u<qŹߦI!p(+5unh Zxst}5mi@ř]\_nɛu]AE$Yl_^宼(iT "뤋{,8RG89o$տp* gO7}) fα3o=洸-Mrrv@:@UPQ$JduV7w<.~okYUywPjphRrJaXSui4b'og:5;Ԥ>γw aSҟ6:Df`}n>x "!%ujtwwD("o!o{qiBn׸\M2)Z^3FSQTcim E\m MSDhs41T_p8~d |}.6ʆ?3Կ4U{ծn:I;i)S4-%U)8QlMo{CvD^=\i˵<@Ehlo FD*PXӹiWS;az!ڥ@ ~%PS FQRI0K5槧mF| _9C4o޷7k\Do#ajbrRXSK9r[!B4}n N͵rP"nhN ]J=5&EX ipZf¼ #uJ*nto:\Lg4ژM\Gqw-8k70p&Ě2&1q-r7O/aB+|eepmRΐ.ƚk(._fhqZ wW) &uJIf`Io~=j pC:& oSk4T2˚%zGU>2BQ?/ p`=+kyiJ ˚>g@YHpW9*4i0ABٓ'^ # 4IDATxMlGߛuHȦ^+!ҒUR)ʍPz&ڞnPK8Vm!ZN8\*5R%Hk7P ;ә]Wֻ3I& _)xѓ S ٰ|+RPGE @ _s&xTqQ,&<5 "W`oaws/A[6/?~hk{= ~| ,|.6LS<4xpϷm,cguk238դPnɯ? og\n)^k@5ZG <[;؉\lSaQe:O j(^ir̶cij-^̭h`ضae90LoP՟1 @T) UE?t^!gS:j 2HƌauGJ ct HH2㶯RfX6z'8JfQ tR@ HA1jo CG!vq>L-@% yǦ` ,E%Uv/1! 6BaMR, ^LVgB+%%] i<*%;r4<;$nacaPPQp q7 }_P sȅྡ)Xd>Dk7tc5f(xwZx2Vz',"T;ЧP+w{;//[ 00^oNMCs_8ńudBk+{=rOlmUn_֫5s[˥;J̫Ł)K2X;-gA; @B4ג7{P-;RডgYKK)OV$oki;u9t]pJ @rlɆZھ`GW)q''yT~urk9藅z1@:Ւ0n]J7{z&o&n5X9R=L@FO/S)@+ctRNS`` ` ߿``0p``PO Ͽpoooo``P@00 Ͽpoo``_P@ @_IDATUU[Q50 vwР3t_|t;PU 6~8~B& QNUڑXtrnL6<6 K<&@w]VÒ`@WrAL?Vv!hD뮎v"42Sd,JX_e刟pf{wAK'5x,f:*f%^ 4I( !IDATx} |eEW9&tIzfYAPP' 8GapTGMCCC#4; IgMrTܛ޲tsonT*I:o(`}Yg,m6-v%B&@ڜ.Il @$@`A   .T4%~([HLFR;(EdQpMQ C e ~"%8 ǔ/Jr nN4lsjYW&AI'*>гFu^Ig,$w؟kHk[ r\0-⠢Jx0Oo )?+ҔV`K!ήT|c @*>Jc^NB؋"JoiCSsBaS'Cr$g4a /ʾeRb|]S'wd翈!k9s-}䬒5u`Q)P90T)Iȫ)q e2P!3Lx2VӤ'6օ)GaJk}JrZؤ{ EHMԸdaskbSx"Ն8p$z4X"OV OWLm$OWe 5a<] eQNjvq5rb4DV5_i2]&{2IL9blIEFEm~`MB;-Pgֵͣ)3D)(Up's~T)b4J]G i ĞOMR9@xhdOD ƶ{)v<\ Cb1k0(| )ݚiAkOAϋ"/CQq  _3I4?Mj"noBa}{ x)Ph=Wӛ9~՛MIl9z&,Is#Fм 1}%R 4Q4,.fLMBSh9:z<ۖinV]"}Ho[+VQeQH]q2S i Ld(-Κ{W}G QYs90_P ]c. }Hu Z$.8*T;X} 4@$ =Єqu:^,lQzm6bM5"e&k~GmH u9! }8{.b͚]80$Qyy瑑;X5Qc&t$Їr~3l3хK_{9!H N\q6GnTL QDg:(qu>(ǵ mTa `H̥C sw\OA2腑3g(:>k7l|.+? ͕a77Cn ф@#m,p}/|pFISsK+iF g7K#Aw/%,߱煮H$shġבv`ksha@bS4N49o{jďz:x `ΉfZmƁCJ(y>\ck7Qntk-G]4@qrړA3?_mAe( 8{'3VNۢSc IAQ˳١7"I:qJztW{չ*lϞ`P%P19b#[4h^u'ꮺڏp֧A-2^h |B|Kգ li~Z6OiOQq x8֫)w}kľaՇS`zk!C@@f\pBv)ZE.~ǁcB֏  pμEޫV\3Ӹ֠UO C*=&Ftkh6H^1mp7ߗ#Qvj$/{BI$~& a5˒v{S6|dנ4;6Y,u!FiɁwzݤ_[܊m*VюfQ'j C/֏Kqjp_{ EC~Rp1(k]Z*SHn} Ӡy$tIg:{BDO=5|=M $8֊ h(w@ )qyXwcNݥIgCj"aRc[BOgCw9μ|ð"Pg ҃me9iJ5MKO3!QzGI= ;FBQ:=ȯ+3OV\Y,=ikNd>7+-{̹~DrJFEd" [ERhNn:=+ OU\FA U@J jI:A>9֏RQA> zvqc5#rĐji(V7 BMNk9lkܛwZ,S(ĔWD6Lb8wZ$PE ^8щΡώx;p✜~>%ߞk߻wJyLq!K\pC .ue@.4HȎe:d&5#׹r׼ܒ { `e&^VesnqP٠j7osEO nTs]B ֒!3RPJ[j:c!}.(YwcNl嗨EtKN*pE&}ys %Y.<$QJ5_/Um!]+tZu*ɛJVdXUt^w부/e}N&O+Z{c gvEYTH%l<ȭ|pTZ2x߻84<46h;w땆*dI9c-OASLQܹU0̸]Y6k[o?Sl.> d$P|ҫ> F]cBSs%I(/e_>^:%< VY)TKxIJfHyP]|w˧9j4͎|&yQS*`9M "T慠sS / +]`ILuάenq93M`ΆȻߏoޏD:~e>WA*]mH KIVtZYǓbeTLڪ"Փ u 4, Ibgkَ ́\(4n7|,e0d!LN{M]vNa n `8q; wtiB밃Uӽx|;-b @ygŽ?ީOhbg| Ά/v&G ֶu9N1<ު(Gr“1G[U 5s!̓~~),yG!O\s D81gA//¯k=Z*}4p7fɪ^%[rU(Ƣ_y_X1drRܭiC/^th850 bK^&:YcѡA*]l/4h~ש #)AoX'Nw@ۅ@+ǥ@?1n^,'.J}˜{/J c"$k ^{NsXT pFX.0Ow$~o!k: B =j:: za0YV\`"[ ^KM(׌8Ŋ:Zto-Z7 ̭mtqR]V{B)DxdZ.6 q}/Co[g5 ϒ[2D`Ï B@!ϐ͑+OuH{[DP|p ^Tׄv?4>~g+?4t{& ϭ{8HcAvm7Cu}t`,lV7r,DT$ HJtP BvQ1K:)0𫟀9]Ɇx}lN!pַ}*:Y?Ð!{֜5S?E/>bۑ6̵9>ۢIܟ51#!kj^aY:f ޓ+ 03it(?4ۯm⅋}>Bv ? Φ@QxCpݻͤzW zxYGiWgF-zZPr+~YܑdR= #dܺ٦\|-ο2@1?<*[yG=#?XפGz(VfpKM[ҮRڌ򶿡KW5>Yͩ0P9_}[&Uji$W1/Wh Q67H쥝3/fWzoa씫n!漡d۽T\6wSbUqen{}Ws_gUfLk挭\-ܭ:_tx?\P;OiJzQ~*vlإUo{CUtnr(2 -{4$1zg)Rnh?ڳeP={~6uٴaFB,}P/6 0--0CP߽[t\UAcRX[ 梹Tx@"bA&Νju*i:iFM۲=bNAo=,3Pxq +ߓ&;r3hU >W9wu Q|:`o^L hUtx~u2 ib !vg6?#ҍ0RVG; U0 ݻ)Z?| > /o MEau[S^pJ70vx瀐=PDGXUZ )7;&5qrVvp<)x7kb)mUOʹT0@8y l{+nO8{/dZS/J/k'^'fHPr#/x{ J*Vb?~bb^qԠ}(3@IUPbw3۞r] \uDx$ UR^|*,ä́fH##IeyiccySFNR4&ql59Nؤ%[o|Qbp? HpPa?pZwKJ ΐ xMHؐuz*!ZkԕY'kZ ~+hxb.ML(;WҼH!=3bZ0 )#[ȹ\W ue|e6B@ː UKS{z&EB@.Gwxb4ٵp&mɕZ L :/'pgԈ $^xE!$;l3 `U$B`M&7Dp84(5i,*pM&4uګx%ŭ8`l{֫`b`M:' !۞[9YDkd+QBʐHYVVGXl,e " ٺ"̇;}pUyg{\݅ 7a Pg(qEiVBBi|M{ &B;NzmQS "3\J>%l#%:F7HGjV?dWYB!ñS>mP +eT-.]*KO:!FTJbnC ;Jb_e| -GeIWjy?hMʯ"1Šx(v53a..zUeS0 lx| pHYs  d?IDATxy%WUun}{i҄t $&HH0+/<>8 *ËAAyIHB" $$NwvOSkU֮sԽw}?[jמj]^{oyE5FYFt\!}I.]&1!gl;󌡵 +u=X-逎 :R~^tzz|:d͟bnt >X_`ox0o.J_pI$ر ¨KztsQ(&XqCP9Ti1!tdSc ϳudBCׇt&\ A6\iy.qqayW RIZfyxENT?坞b.6y֑e,G>LMs&BY6,sL UNq"uHt.&@K+ygV։S'U͍>D#E\:L 8KGq:9mkB+4~)ai"!whP]auvWjePvJ}9YS9GY*|NJ=:3Bh_YݩOYkU_ى4x[u"_г\^D<^Jס̕-LreL4XQ<0t#,7Npmj+*ח>td~"E9ʙCV ;WO0<=BkEVȶz-oTFos!rvO{h(;Աs/v?P/"BENe?KWoC^ᐧ!!oB79zm3?055%aYv7l ?9)y ׹ss;{12BfaZ4OyVOJ+XE3rCN9*q#ݷ{ttS>0 0VǏObvfvg|shdHISdC?s9!;vGFZaщ9Yiv. I%@% GuW"0 0V%6ӈW\wa[h3(]f1 0 cfh2Q6C.o\QGFX mɔ2aʐ0TUϾ+ˈ sِaaBkI!τJD`Tnf10 0~@Fm@m)w@QJDY50 0 cU#Vc9mGZHtn0 0^-72ʦn˥f<f*ɂ$IDcaF_S>R6 r{'(aaF?`Vɿr%u:6nRar0 0 vkOߵ7^y{oe?w~O~`3bb8vNx.O\.i"F\r#(*&䆔d1aO|?yaϿp>G8{=^uU8>q|It{L!#EAdO` i890 0?w{So+={K<&yF;}{cbb'6m3J㲡(JŦ6]ҜH$Sca A:xW mib86mx{p>6g? =#1:Ӷrz@wSfn.[T՝/ 0 .`K믿?~co9Wb39k|KxO]ٻv=$KŮg>wzmqփ:жoߊ{(4Gzo^E CNoC)OL4f1 0s?|ee/߂kR={۷ w9 p71ǎg~K W]ynݸo`3LxǯpK- SR&/L)("'m)ؘ/aP-7n=fV5oxe/x~߈?OL]rs쫥f豎Ry#~7ei!\^Ej :Yh4u3 0ss_SngA;óg~775x >Oa83p . ApUf-۳w?^/x^rK;t"cY,%GozR0 XLL>^\dӦ?c0>P"駮snسw?>OoıNl8_7MK8~GE)BTYȐcH0 X VۼyY 1}6rwAsSGUNg9ypR0 0V db[y$ŅQj:4Ņyg1@mCNaa,m (V@UW V9 EF: æma40bD"'e0 0 C@~IL?H8۶U,š4aa t Je ;WfJ"֣c1 0 XfȻyKMF$#׉+.|`J0 0 cƔ`kE֟ᄭ)O]y{0 0><Z)xBGNr< 9aaE:sSžƋ1m8aWs4cc = w ȭQcʌaaKm$Yhuȶ! ]4'/W 6 0 X(ҭENDi0 Ms8+DzEoR0 0 _@w6۸2\,LfcT|n} 0 0  QL kmnӸ=[즰aaF?/%zFAa /_SX8$AA߰1 0 cq@Yդc0Szrڎvwnޥi Sv 0 0 [?ҹcp-4r<2h&0 0 cAHͦ (o3rz:#m=0 0[)7Ԗr2|InXdaXZwOo<)JŽ Y 9{V#ɦnaJPtn|m}t$h;]:nYaj`OsrJA%F׹B)8-0 0F}bLAShȻX[03 0 0+gep2K $f4s{GʍlaF? #K@*6|D~1܂5tc0 0 eb:Ӻ&M aa}m> t^ G9m;Acw4 0 #rHcAE׏(3"cK,Go krԹeygVg%^⭛b|ȺsYH^޿2SVu+Z~M:{%s)ߡ6$ ])PC mQјrb߼!F_²Ц.STuNUP[7_^-\e emO2O*?_k ERYu* [ vɿ,̠_[`<"2~ӐSV&8 \5<B bkcť]uV<|,/tZؽZܽ,*D;)ٽR^DkHe@kUK<.xciKHݵ_atRpa,&gr1}-!H)-skK:Fݼҩ۹-$텼괏8놫9V]ab롮e,Xvo/c_͠9+5\`XZdz "y4~=\o5%IN@6r5u<SÔ;MBYBKB++J_OyXhIҫNĞX}SXdƨi:%*DJfd|IzR?VK!ucZ4a$V?9ѱI" u?z F ֨=Z)V_zh忬uxZ9vKS,ު^4߲Iĵ]+l[2NW<$IROEu:ri/)>LM%ڿ2]+'D9Z;V"@8BoIuiZ,>SbiҹXi:Ų@H$*Z>c/׆+LZ~-+K//ɲFinkcڳ/˻w4X:X[S M\Zj俌~˿<_jꔫI$I1 .:p|wA S^r9W\6DEZ8-x)l/o:nMizqI ae\'5ޅQLpeQVN~-VOeeϩlU6EĔ~V6T# A h/ƲW.俈?[Uiid1b6&\ NA{ z4 ƔXDZQLe2Q%|u1#&&ÖdܼgU-M^*i:]׺zL)״xzAvZGZцs(!,- *eǯǔ~b IY*;ޘUykDZyYjC2Z"do? &ʔPaAV"9II!")6r\k:2e.u$T!M۲+W eٴ&x<|VIA[v΀u@UiK_buU|{X^b 4T*>> ٻ)AOeosB4}P} X: ϶\|j\g5?v{·ơc,P 5u~>$tS0X:9>5v4\d'rSשAP`lRgFȯ;ݮ Sl c,'K+6.Str״it}~vor._U4IQنa.g|5yue(sݽr );0IleF9 $X) h۹%ir:4|ir*4GʐBp@.'tMl\@fsKZF5M6r} p厔c33r"M Mv호5F?fi sRS;9Mjʨܱ3Su k]MµF܈}H㥐C?('6Ӊʏ@y)za' K30E֔0ٙzbchOG phA_,̷'073hm8y0&_IJ&QMl=(5Z@w&D,t2'#ʶ& jM^xmXIN)]p:9|YfO k hIq7#106{:ИF=5eD&4֤p :MXܜ++i,i54e_ߞ#ܓHfg6N> =)H[ 6Y#i5'<ư'IC"8|?èaҦ*7WirXåkEÜ9$eJyǰoaG" i'jzľ08GqoaC-XwOIWu;Ƣqf&ymӶMƝ{;>}vs.q!~3}c)S~{KN"rӺM0Vץ=$|{HLEF;$5skN!tHj¸}^wkz+j9{7c߻oGcXLl|hmހy8pH]R8L?N70x蒨R` y&~+/=~KEy mieFYc ɈQ`ܴ(V*;S2AbO?3<dig )[H1'عޏg쨕o2v<:Ի[O? ^,xq8ĉI\xx 5;w< [ڗJd}8/a> g:$cw^|w NZIe [ȟ>?^&FOx?Yo/w-uHOfI,4@WQa(;˸D5mQYCؐ_? |IQ=:}| ~^ ɛnfl>i8̳LU~%xqs}܇ /x?\uS ^aÆ?;vݻd;w|;+-8lzG'B_Lc?2s7~ g_ۉopcW6Vq&߽އ=.N~]oǯ}>LV0b28,Sp;޾8F97I$7*$}~6+#g7ĔZr\x?{lz6cWK?v}[>~/c}.qiKnOEϾ[O?-x5FŽ~h7zh7zaW+~)o<ˏ]a+͹Y~]ͭ;0G'm~4v4qS^Yjuj) ְ̬yi`+Kn:ҭ}=WbIv_6ODp}H 7Ow>0."|/bγ 6n؀ .8\<džq\ \rk֊pǞZ)q8ּz׽x}au7x$5\)luȷIwۑcO[xh#=˟s|LVw1^=e5imZ8!LO׫ڐ&'}jTf #!w>݄ġ#x_o覍8!u@:p#8Glʴڳk=0.}Ÿgaqγ{)0^wkpΎ?^Wc|z\p@=ްa~ĭށ_yo;ʔckugopo{]Pf>gg?m+ڪYi6MjߓCoGpsvT߳QjqU—S#t̗).Ux3@Wf؄J(Zhr&9] J P>V(-.~f?{@p8"umlGOp3bq%ǥ ϲoܵ[O Eh>uSHZ⁹]1 pOݒ耍W'ۘQЩx$Ry!'?Q& M138p)w|COs̗\F\8{DGh:MC.^Ç(aT9j?5-[kF5cpI<~OG? uۀZx7'#k,"MX8)$Iע:y pBù 6/9}Q{LvK2`%/.~T 6MHun A_\3L6I6 1Dl\Ε{sS3pݺ ik-`a8O\=p#5:d$Nq%π{ fŀ}zd~vYίW[oL9Mw*oa]8dg4kOsz)1ZӄQa]]H18d:Dq 3 sf9FK5^U-u KWn薍?SZi%IFoc玳BzpWpy|>r|3%.I[6czzzf9߿R8wݍݻ-MǻCNF~E8O`î=} 1__C8a908s94};jU+D=|ɟ_#x[ŹV/Xj<ɇ{~7ZCDnK+MPl9ug# USoɺ<|ax.8;p# <-;yZa!05=SPw G^znNLOO⍸peƛn|7bO]x#nƖ-[pe3~ϻ*0Ӷ%]a'tN|&Ŧl/DukF#-\g 8ķkYgзvc/w| 'mFktHu5۸{=O^~|f=|..wa8޲e3gԯ+75gf3{1e39gw.m MijkwWcccx?~/.좞fw(7'7mc?*O<nS@i]o&r&bWy:uIj57g*^~yצvbF6mM8a-'nLS#xkҰ4;mXINM,d% Z`lzE@ K78nPw֑r0R&';~%s7?###8;GGqޏ0W`tF8?Rd _]~O9Nضm+kpM7gEo`X*{{^suguc^D ~1B{>L|v8w@ipNV ^WɟJ/ ?]"o\3pcC(2aIn9 цdS>z=]]O¥ƍXT֐kuocjz e3vzo~58|(VkP/ވll۶yLO`zzS3+>/<#Gnll ~ x!矋[nWЋp]%/~ae%fwƕ_tdg G{v3ОYtz u?1 1c hc3bþ&&^\|&/_ |G_GFLi;:eAXXir %EZ`XiTΟGΟhCJ4-4Mq z=7x?ړ)g5V4>9>;▯މ;4| qW fnW𑣸>s2<󌭸oYu%B8Ïܽ/"4ba+5RӴ'dmٜ#w@gӨ켭} Jc#'Zcr8$9L$ Yo^xE6n, M#"uvuh$&Q [쥥=] i$IRt5*[:E=8 9 W=ܺ6=$|>GMr:X,ڰ̝f!F51}i ^#Dؤ,p+] Yh-U=2vDkfoF{(Hgۡ:$H7#oWaC͠XL cșCM{"CZVMr<^A!]b S~>@X OSg_n5HSB hO>IO}L .{uYhIXB ! %>,1W!!} i ?"R`g]5\uIwI',lnP 4!Mv*_>3a 5&1874eCJ D D2mGˀ_省 -G,_aM$I O?60!amwH<:I%]C"圂\pmjo3Hlj-a4|B~K H oWuQ9eAIa}rkF@K4;FAjl"6 DX:y︝d;=hkj˝z?Rb:cKO-Ds$WS8N( ?)&+14bʊ< /u06l̰>/P=A}e7䐲ReS ?u:Mn2#JӔ~m!_Vs ] X>EU)0V1k)w ,ښ4=HO&gʘķ>O|q=EiL35%&ci6v XE$މE}UFq%ɍ$ 9ENbVG9KRHE{xt RXO&18zQ^}uBG0֡ ZQvPL1pFtP13@ό}T`)i,2J81"LdrS& 9q O)R6uTwGO,>s ٴyg>pDŽ<$I&jsoһ;sΥ@]bCkѐN¯M TDf<ѥ+n_ cnKkN5gɟh% %>3@GƘ´l'L Z߆afUa^0iһ1Im&o f9Ioa2/.nr.މұZjG?OצVkYJ4l$ZB 8i;g8i¦>0XĆb%Ƚ X4 i5mCnyzI4sɱO!lK򟡙QK_Eaq]f)dgXes,egZ?c5SGbfb;!]$+y`DFBM!v멽P͛7b ɚaxHӴv'jgc9(-1#ϯ"L efRMs~ /oM:sa;K *#bԘNf; -r)6'`5"6b'̡s 6 ca!j90Chhl.Tjo3˩X4!`AZg4k f\l8MӡjCϵeL&?[E(@M=ݡؚæA]7 caľZVNVath\Zw(:6L2׆A50G9tskFSᾺl!߰dLvL~6zc9 vMٮn 9-8ԓh,C&ɟD!],,2?&}"`ΰ>1ˌt{ +k1'D:a] d^^βk1k& YnWhMSf4uA%w'\CN)0M$;˘) c8H5h`ދ\cGw؉n s`žMdCPâ060Q4 X: ڐ0d?;Ѕ^NmlkZ)J5c6e0 ?(a,-b0 s+Tp v"`~#z M #ǘk 뇝U(3& YnWdOe4c#?r)g9B^q#N5"r,L5)'DniUHl_(\Lʭ?Nۀɟa,鿦]/lvX*FOr+>B5 ! L7lFц|v 9Yh;Ód}h '2,MzゆґN ch3q9*23:5+L84I:(KWM6͞Eym0fA~RW'Hesaha#65(ɛ`Q,|ْ'M4m>)2:C9RͰ)rL !^șZjP4%Bp#E\|K,4d|&<֔me h)\13R6[죿A`!C cnr @Pfjd/RTv]]jvYf! vY`40>BJ UN4u0V)pQLh\J29wru͏V BS6 gFPfHh'GcqhlCB/ ]H#K$;g#aŹ\704a}#wILC:LX4)qfZeXiR*3_Rhr3&"4, +Wt.Wa}FjNV N$8 rg qh214%6G""LiM@~ڶ^W0 cQB#gdfp=Y@wE`mڶ}!F HoS ÈA2A|gb@6M\]r.F·Nh ڐEƓRCaA8lF /l,7Nu/SgV\ Hql`Lw! MnLqq&:yMl+0)rs7< |PaJjCNa6?ɔ+cXSaP$a9sR,:R ={4]vL1ͺWueN|.wa=4M]$^D8&O,6C#vN$ bh4wc~ ?"H&RG| rvvݹ;1,fC nA35ew-_M?tV2?D$gVM[ LߦXih_ECNt4f,7!Ʋ7o jLqb3i%#TZtU[<Ę9IiPhM7 cH$,W\&A 6a3~duGiFE|g$t{{n"3PjwxF c8z44}0 mg0^sH >-L!SN),?~7b`9=ar8{UnA64]W2){g7Maj/~kyͭShI )9>ĔM,'N,rX)5esb .4e[Im-( ?|X]t4M05BdKL:la+kzv/ik"7>"D<;[X/82">eB+6N:QXbJfSij2h46(+MIf4),K"3:4NFF7cRjhijzҔkD3:O|gLa0.ϝq_n&q^Stش$wSGKQ_ڪeNV cEמa[p_ag cU9F*6 o8-8t KM>jg @Q)q@ ̜fg;;607qF$[bh5cc:׎vF/H\{[iL1cSÓoeMd\o~G-b]ЎIE"KQEOӓ$0; LufNU|k:`F`dsleh Ҍ'4m;oSfRxi<7)sՃ2ʌ'dnJMՈ9jS̤ߙɸeMwMNk;_n% YmCM@q&yg휁 J㊧TNarcXd!fX6j Û< L( M{1y&%gF`.39YrLc`<6Z}M Ïf3ɉJ2?r\3rP}h2eypG;VO4/Rvl:Ք ua PZdX]̧o7 mYa[ WhHi)6NlEMsk^4+U1;w SnV#rAbDža,%L&T#D"1ĂuW .XhĸVд*G_mt88~Zͩg6kF3cCN.Sd2%G^>|Cgի8KjwQIH{7j _̏&gwѮ"c䙝=9rYmV2rńMrgcPLHCChӰg<ԾhQ;L<~Sܜ6dNƪ)1&1Rx0u;;WPh 3IîY2'E{>j Gb2_Kbi [XXjuy/a ?"h2&$uys.7DcUN*/,Kķ$ m,ʽ `Sd Gbr(~\$Iv `y,i,OZ9sP3 )-t]Cڜ2\-HS`'Ntx!ءAdӨ LN0TcM;f7 [7{L)CnYPbVVVfr89xX9?~O>:(XyYkGٗ^+3%3)hS:Lcph84k +/;Adt/Z; Bpm̩6eMYG=4#%di1=C>uTv,1+H` jӘ" OecM~hF =<|OgQ;wi䴝*+XLmU`g7&%1E&(%`tbQSՉZ' o%g_3Y兺>ufL~rxv9h&e6E>cEa60_;O:tqEDg_G[5 vgɦw9_o%k*4:CPyH3454M։4|eiI.Pr"6aZw?3a7Xxٿ~g|~R7)F84kScThd²ˑ>4|';"JhCFj `ZIWs͘륀LL c3p})@JӴwI4bt(U<14) 3kR0;Qj'z*fFRX)8v."h&A 5La9thS{XnX̿~#/|poMvJC'GZHmcbUS5zi2tf53RQb zl&r7ݛ^59gh>5(3& K_X)wه/pS-ya BsyYNCK9~޻lN)ͻoFj,?2OI2ߙמg:C+s'a?cyY.|8I^d)|ed%~ ("dL'm}PhиVh΁NrSfjqAC}l ?cvedi<؄] :4+2d11EvR;5V6}KrSf80+HF~ڶTj cvҿT[ 7Nq%&7I3Sh1T466噙xkLe_ԬRΊi{I_n W>tJ#^N&BSF4Yƚ5kɔ%?^>!'2a8'|~}/`eIec2; Guy+^߿_5ޑMF?8>׬pS)*Riڻر~|4Ym\Dd7HI 0al<ÃVj4v&6c@LNtrTfFG~-,3|6,5  ` G4BsQLMM?<>%+1ԭdgxrb iZGqN<ObjzpeESrUΡ2ě<~'e6704ū&*1ibjzǎviW@Jr19an`AfVWUHyo<:qfgӿa1$D/o4a9E;+AќB}i±pR+ 1m`zݧjb5Lc:=w$/⃢PV9/)M.xI_4m;该ġ;?{mWU#O}/ PZ&ifbm*|YY-Ez2QNc__5eSGC?K@A5g( vScus.,q[<CA+kW]$;޳4:(<}ɇ3A5vz,#ox0e8^:ʓ/YvoH/DF!^vٹBEB6_DJiSWYG7H9)m)y䀗WKG>#su׋lC&&T מ 2#ʟ#=HydYV<;|x!Jʼnpr gV:p/׈YECN^ syd=H> rٗ̈́HD&_ RK^Iu:y^I>ۘp)m%С]1;˖Gt|ٽ8+rCuMjW}c+s47W›c%ۊW:_Z~"pNc5X~RScN:QRX)24T^8—|>Cfg:B7=#~3DzmSx!kt֑6@bm9aLMM+nci/'d D-4<8_x)):/ HHb %Ҁ<du>"j2<: ހx/K S&]:)Xd'&뢬~,Z')\5V_14m_vIJφkuy.~A7-O,(ɿ_'yߠ)`j߬pworP*+0HeBTle*P Ԃ%PiJ8/Cԝ|\_E]Ҕ|ˏ);cY&BYkS2.%eV:,UaUnԏmiEڋBxKGֿ^I;Z&DQ:477ET캨JC/{:5^) I^NXXW(dL:o MI?þHXrv]anIS˩fZAE<_ܵd{mڍ w.洎* .-Kw2g^#psEB:مRQ5M9-I w.3%!ʳfHKm;w%xxa$ι,ة,~[H* :ݛOe^@tBe^E|C#0Ix^^ O2?~D,9S^)},TOTϔ/V6`5g<ՑL:GP7T.B(y>) ^/Υ2[3 q4+kʟ76:S^x{!1ډ7FH?3"BAy2_)-.Wٳie[@<#,X2R44P@ 4!@e`RfzT6(eY c&0G5z'1-W5JSzT~R^Z\cR:\5djyt\OXs/(De9V@6K'[Fu&&&딇?VlՔ/qJU M(O"S% ]YUUi !L!Q^#y9}_,"A+FJ-z:4`ϔg,Ք{I}bM%I6{)ϬN~*Ok uӁn5Y6B 6Գ?7_%\Y{*+^_.Zڹ|]nvh M kYa aybE^Xw^,A@[IΔKx+?Wci,*#V/~LM)/&[E]g˄PrmNQdD4\ôW +x͵1~NIGKд?X8([8̋|x13033/~?7 {yVZ^螲rR@gZt |ihױ)k^ꚷ Y>j|xW+kY^X\^)+ML2^4Le<})crkYMrJ|/` )RUG+  gQIuVT?ؽCGHa :WMh%;Q yYe=yjuuԊv#3 Z=dRu8+g3K;eJ@Oϴ,-ɿZFH٩}B~ysr'Zƫ(==JC|-v$ ݛ]\8WUqjq|::ҏk,,=+GG뺤u VM>^BXbEȵPIOȵZ/S^ZGtnuuś:K+/\aLMM©J >sZ>4RIsLi6P=\s.?l/  Οث|<>V+˿A'uWn y:%Y>و(@퀥Y8}.YY P5eyBCEJnr큞3 '1|}z 2%ѱYC'(ꅵWGwdoo_#M eX*gTHi SIL==2b/\2jE+TТ u\!/<To@e%=B]u q+߁կ| aTUV7%q~ӽٹPf-:JVW`.Ӳee/~o,|&&&+OKJҨr9a/a^VZU/ D5N ,_8:tYWEJɿ?d=tlbDT)Dl]+t@N80TXgSXSY%lJ|KRj82ι:WzXm*VKA :xƾ4;7VVʞKG#QYAAUz#&,ڟ:9Kw&!׭l^- ը3әazEwr i*j"ԼS(Gz/%딫J(!UBeF+)H7v*m-l_?CS&w{WgH݆]֘::KC.V"Y@:.j锅Y,O`azy=PLM{:?*|ٺCvIENDB`admin/assets/img/oembeds-image-4@2x.png000064400000102654150515074560013651 0ustar00PNG  IHDR8@ pHYs  ^IDATx{duejqF=R;b(3WU y1ey^ E `])Jd*[Rv*'o{vnq}u˓)G~-·E Ob`^W(YYiV]!0W3 L-f E>q(uveTUUwe ޛlsnl('g(_h-|dmxP0&(3ZpY+!Yn^ϭrvmuMXkϥr:hc}}߸W[y*,BnF@IT(Dhɿr{{nݼ~eUv{[G0ɇT(3vMY#},zIn?FEQ5sτED8c*ET(FcTڙ)Wf{{=kΥ2IZ{f୴{4/pG)T(F>4 vu,ndQ߽ROZyvoŌCf6@Qf8,ӈQ>g<0(e+3vWYb L>p:Fʴp:;3=x9,nWzjSiʾQf8,ve0MpR'T(Jee͑b{{7?}}:kP?E]7;q!ؕuw> ??;pn(3ִ,22nnV vqރ&_w{vkXZZ<ΡY;?ϰadz/bm|z?m\}Ryʏ "LNe vb$؟1WK{72wq{"Y_'x}/z"oaav~kknMύ|xfePUv{/Uc[pDt&67O2 x`\\_s<n| s}[[-jfȌ*EyT(Hߛ lx ͤԗ>g^O}wco|#o6oYċtf{L2!MU<$KQ.ꃣ*h)?˳WD ý{p#kO8Σj鬰Ih1*W0y/oE<1X/G̤RD-8, <5^S9&̀$)ʬG%{ fP npM\S=)?V4h?|M\V oqsD@<:DyE>/$RyJ:V*N܃ >8X^c1h;7i` ZsXa9jQf 8ʬ8NJг,!Z;VaL zpp8luu :z z_^ڛDMoq7}*2QfTqHe`uڥPc?m?9x? eDqfe?&hcCb;J3ZjQf8,Ow$ɞ-:!sJU{ê+ܥ?3~~p>^7mxJ ņ%Cbqď>±ޔa)/8׫yu2Qe\ʱ"QTqvQz9J2jyQ e6By㽇V,8G[# d:RΗoK S>wU=< _RfUD0V nT#y7jDIrjU5VVuuZy٫]󱆕(ǰϣ%rUCWRP 7|Qfg3xDq3!+NU,r=ZOh V,'UUC iw͠`6g3_^ǩ*se.a+PXNJ:g"*@'U%ݨd5k=w0+19ƕY+Z>͵zjh-L>9_Ftq/Ɓ PmEֳOz#z,4o=81Pq̧c!V|z*= nyY",S%9Ta'C~c*cײ}Lg1 e{ɋ͙o<뾺zmbERɐM 7S?ZDaafᐿUn5~_*7,K CJ|CNHXW4!6X\ [p69zx3)Sp$]ہ3|,zG5Ày7,Uy=ؼa!%ή_nUb"'+AnE+_>FK8ʬQP Hk:Y]]i88H] ,k|Ͼ Z7A 0 JvR8nXƹXy\Wy%:67yyS>g&D:Ru7|NW֘~kת,[(נz?Z%\qs߰J`yZw8,Q| @xTN.rX]]ƊpRBۄ &{rog7wpy9rn'(cbh>:G5A-7y& NV|wp}kбbii+KTP&rgw߷|( sneww{{=KK_[] /ԚV5eyIYZhq)sKYk1lbqr$ _aqa}}}{{=m}f Mx^~l,_B;G5*mP g5yVkqre|OM@p&Nn=7Jm(o4/}Ǘ^&P+c19T(b E3'X[qD LJ)DiJQ&x\LVQ)ʅ4$ SL!*,1[ͳII(gM9g'eE (tT?lQFNҤ*cw9ʙ7;jǺ& 4~ƹOö;w=i򏧡fNRϵ/ߐ%S7Kzt{nԕmy`,08]PHz@``[5Wm3le ת14j>Fct|X)C߇]e| {~? F\1ge0 DZ}Ձ%:^iڪw*V-3xYoxvaeί8^&Ug2Yfľ|rZ$Vhp@;;{~.z/smt:p|yu\Vp_Wл׮ x8o ЃAw?_Om:'GCgn!Zs̏~#rب!? C*矓JjE&m6>Jo`?-Td`eb꺰-3aǫ8tȾrQQU֑V*kRչV +?0q9LTU(R{(>wPZuJL+37=ۻ2V5Ѭp(7n|m,x/~[^|Ϸquu0";Ky>7>8=ڧK(`aE=ʒ2nbдU8p=t:.MvqcoO|{3.ŋ7b+gZ M4V -\}kEʛP{8FIwS .Ix W.Ln]* VYXI:;( 3![Wݷ*!2%B'גIվa0Bg3X!ZG?%gz;$q^~a{g'އRk{0+u_<^kM<+jr7e/_Ufc%5iA+hT 7֫Ε- /a Y*d ,%UJ֋,^*b"~eD?^oTV'AQ!9+Hc):Bj3=X_?f66nz?J}i,_D͈Yţql qY?7pՇx;7p}sbǙ$7bybxD96.T;[4߸r)=V_X-n^zÍfU.,g6{;yƟo~k$f5 ȷRA'\"g!v Nn@vbgwO΄(vm@񵏡O~Mz [Xn!nsu4R3fgg=ּVZ X^^Z`g"2Gxv-Ƙ'䈸aۣ4sS8"[ke77>>;󯿊>.'u ||}L@\_[9P3bey /|ιk)a*ZcѵuYZև@a68<< ~,.\Wre괋0?|7ox]߁w}G&_{ x}&c :ϨP#ZXkWb#,Q4<{&Ԟ̉ \29g)zwl5|b|ornxeVB?|}^ xjȔm1rW\Q>U/X=$vda^P/rdLXsvN4}%wop'[x#m:-:W;h,{8,|כgϗiGQguX6:1lYdCLl*xBa\B_ |p}8~nlDֽɿ|矇`_z pp\W웞yѯ!紴qppЬ!Z : ⾼{8Eàg b7Ydkd = YdRQb22^9 ֠ih 7lw\Z۟&~ޫ$Z( .ciiQf @ci},W^"E6lEGbY$(Qz7TJ$\+gZ,--b}vf KsΜࠃ_?v<\kұV{,_cK]Ydd ,* rrH67d^(!Aw_whn/|.n\"Ȳ~,u,>;LKeYTJɲE{+Zk⬭L\JN7c n{"qfԟlE⑟z'+Yd7뱳Ȇy&XpɾNc;(J-Aar=koDKC;88>lLrQËwO'n~4̗_,>{f%d}/ppDYNlx *p@8!HOJȆc|ExJÖ%GS|]ZvCۋ Z7X\l[9sxHC~F Z k?)ϱ˿Wz^qژcuYdZ,WG| dXJG¸+E$Y.|N9( QNaޙ$ c",lw5:kR "X~׷WnQCȆ={e;T4Y=ʐp*EC&edSQfO6N;s8ܺyD e8^Ï>^_# hyԔ9yt~fr G *YDPb4:Nr?^yy'?KkLf,#p^T+gk_4 ZzԖ_0~奉k(T( A> 8:_͂:bޛmiv~v{h6h/3jGnKӵnU:6Vu 8e 1=dk蜳^oS*L5^XAY|rĩ^Q&=;&n\_ŽWn^qp #=8V*}R+cpOBĿ8;HM __̒qYZf_᪢(7rRhHA-(gUbjU91C{XPeZp9g5D7wp}Hk-֔3gJ?ѾR2y<~25N[_񓰶eh$BZ+-7U(g7E({1>T2]g(Iwٚv1ΔgaL s6{GoSfy%ߩVkAbqVcp,ܟvQΜox-/)pJ_iR% APph{E5c>qN֢6 x fe01&Ie (dh(+3BwM@fGb$|m Y@quQf Q18wfX%9H(3K)nHxzM$?eWc`uxJ! hݙfexD2YTiqsꃣ5뭄v@_ޛvI*ĉFL,Z2afެgRV,n889;hѦ@7w2<<[LJgu{̴o2;K-%YkgW;! T'gSF܎==ŽZq Rg`,nȊil%GJOs;6.6Tq[xg1 (s͡8ؓsObS;Fsr2^lȹH=m@߉o(-<E3l!M|d~>9$Uo4xnּǙ42Kxܽ*jTA)hGM$!L eXs3z'$݌f$ӧxngڥ-j ^P2~dsH7FTהݽ6^δr!Atb]%ݓMh)?;y7|Ƞl򞬢ԙ;)Un偊p} {Z 2xu {.Ea.D<x#T+u@fك"j(G47Fp5.QsP+dpYǜ-8S0'cE;1M?e &QA?rOZm1VC^l2 A%PO0pOpU{oZq.4.<@6CU2sXkxU mΒͭmt:.ƥ{ ?V㽗@j!Ϸr7噂2>@_bgwO>^ށ$Ĺ(TWe!QZQ:gZkyvvώ]P|^E)Z=vϠ՘vI.0R@sGGaPve||E8w`KA* h9Gٶ"x]&e ;@5R\\rӻL0nłzњ_BI6}E8wu$ |3$ !8akkwŸt%tjrVߴā(^Сqu6Vf4Ұ)Slɞ}U78oJ;AAbo~ɰ^OGG^aCW 5`prO9cxWf$%@ٚIxagwOcLLJ}kAr6R#<,jr0uBe(I 4lbB%Pdhթx3>6l>ҦYZhIWP 2O a[ZpcG{pz]K YQ=Zb aqU9_AQKt]]3:*G+!KdL 25!N^ɫ2ϜEh;0&X| UXv@S#dzlLmd+F!NG3}bBiCpC \ =u؂óH&(qe0q@!٦z=Kd<^]ysaa_ֲFXH*bY%$FHhX< w7%3O.)m ƀ ]fQM7zʴqG8I&K 9'yԂ3^/5MOTBeא4 ]cv^YAJ69-bGCx1dP2#8 AF転Ԟ; =X|({5c`)虢CIOۘiF2͹94 vp5J~N<|;2ԌҒ(/ӇI7B#+u@D;%XnT#PNצQM G؂&(JrKzܯ*5"ay7sſS(EF7D| qƜvpln<(5'8ҰU9>2|eZy\:_D5_8tD+~8i\pz#ʰ|1YkbGJ}&F,<Θ~uۻkYL@iá(DGbՂ2휓*t(&t2צi4P+ĚtԞ CQb̈ FeR{įR N<1(C)nL<&%PjM?Ĺ8 J͡[ iRxٳ#x|SA)!͹Ot3:c\le@)A_ЫqhO&eWZ 6(Ԃ]?L r4mC/Jް͒*5 p ~='/,daa_Bdt]<\7o IȆ^ْSNxE(1ƫq 8C1W@Ct!1__[Ϝs—bwv/[_[C  ?a( AȔhGWc۟&HŒGjCKwkPE/{hߺuOlo֟wxtNGQSWZ #7~(X#ksI@O<*!*pS3 :Mf8$F3 \z>ǓγP*,ϏA @=~/PDR3)9*r˲C[Fe92.ˮXUK· 쟷k3a$rZStnx6{^`:D_+P*3F>5<,|'!7sP`LA LU)IǍ7N77 ;c K^\I95sf!yw=U\q]FUBLTYY۳@i\&&r(` Eךš?KUfUr2W]<
o1D9D*Pb"s{8}fMeFÅQQ/LI#> 21B$ː D(_r%ȏ~N@Hʑ? r 3!|o5|q蕟 ou:CUdnn{agwkic(Lι$dY⼋C)pqC QAbO\ 8 4ꙀfIu*i@C @"b9X\5*;˩5!qOC&,r+F2'tuSyeX{CCrO 3d\{=F&28{vYy$ q)o32Kw?.:+s:LU~0&6 !:`"D&|߃۳8}Ic-\uF]"jp(ɪFH^lщ}g/kMO,qαĿB9 >l1 dR~EY9љpkWiׇ8B(dhl)IQ.>`7NPrRZU 37!9%Fp U%fD~l}^ƋakXaD5,~ˬV|(-^ LVd-%cU@5EI9P.. .RDmH9Y |Lvg&GbybCT5>' h-,`[#P. kquʴ1 VRs W\'+E~,(D g%WY1قcQpYyfjWU(t,x_"ު$x(E .0F&i૮o;Ϫ-?,¸,vy1xV-Z-*>?^y:S8hU˟܌ys7oj/XDiDQ&hhH#& ,7.qBJ x Pq&7}?"<+ icM؍GVZeIΟW>bDM_W)ۋh~/r`k_CDz.3? u!VK}]愷Ø0M\Qf O}mOsɪ7yO[T"SNV K6'..7(R?ncCW'vu)րkw88Eɰ3TҊfl|Od1; g'. н-8#5^{orݳ2brR(J-WH2;D 0(jER ʆyN~g ':A#ǐF'׆?Qve Ezն|2ʖ)g& G J)<5 5<]mólGBHBGefQ/\co3aM*zXq%bJ! ObTe*Ȇ@#ͭmܼ6b\Z»hLRg|9D%"!C%!zɰC 76:J'ĺ4%`EbeHQ}8jP6,6؆6)7 7{E_o@٘PvGYk? 6w`"q0`DM>XkϢ5f߻Xkl7kԀC4RFѦ.8Hr(fj@1h\ˑ8"f9+wk˘o\Sx,//kW!|;t‰2HovE#2J~ ؼzgk љ>2Mn<[7ctE[7?XX.F|ct2 Hg`aM;r)ʉH3v#YBIBlmk_pE9%o98e~i qc/EhvnƊrٕqJQf\Ќ%}OgSI5÷}K}&CfiH(uĠtOS8y]USjM^+Y=\k̽&9{9Xԓ ߁؋v崰)9vHw#@ħ&-%آGln9r+$t}s)s5sQ^ixj 7*Ǹt]vB/( Zh-,z^>z =c CX44"ެ=$r42$^ G^/nõJv_m1HSh I )L$mcss k-[X[]6 㾼л׮ x8c<ЃAgƯ'ԏ>Q?yYo!  ))^[Z^~O߾}CU8OEyiHGa+iVI\v.{0T09lo>2.{|O }?<ҷX|]g/?sYɛ)*Z2ޛ?e,.4r!qak{~iWW@Hycީ{o97U>Tŋw{{>@򱏫>n[q6:ϡÕo?r_cK]o|WW'~5Ld}iy4ʵ\X_`D9'iXX?j-ZI\8AUQ.({ _dϨϖ>:aoZJLxt?9θd/ߠ,cGx>r?s}\1kG?a\4[Be<ס9iJ_~˾m|z4p̪9ʲq\U|?UǪچsq/+dzfC9Qס+sHXH D2`qʴl)jvp}TR?KNq 2_Yǫgw{GP5q㧾 Vnqc$ɱadk‡؟gIcEPebє7IJ/ y=3wt-xTr57!1, N>L&XbSnk8Pwk輣QD,+^FP2J>~b4Ra׋ t;-݉9{TlkO8Σj鬰IѸc{O|7#{f@?47yC +J\n;{Z𒀩jw:f"lEh}E6[M/ac}JN&V'/07?Ig3߇\ |%bM^RgJ}qu7B{ι'΋*n~ULƕݘlaNo]*=f&5Ǻ^D32g/˥1za1MoЍ%le *hYlxeܨ9̏X2X%R}5a]ρs:4{.r52M/XM"$~ཇUq e㗄{? GYfBM3اRx<>v5.Z\ї>lCPeuH{' њ Wh߇]'08HE=#)Q}@/-&&MXo_y,|7yXn!ns|pX+oL6"} _$Cl}YJemnJ2Јs]NQ֩rDf+C Ʉ;GyC+̗:Lra^7IR\/~uj}N,!$&:  8 H%]V,er^E &UXz4-9G=IWWn_缱(snﭿP?/_4z\; xޢ7+K[rx*‰ HLq 3]»c~֫:&e! }pD$pA¯JXtum9׈??88ULȾuU9E},C6R`ʗMza,r  zkK9ux\$>tRrE >upr>WY?? syеTDpIN,Ub9+_W9Ǽ,,;.;w$c<ʱ|on΄0%e$ㅅtީ#vt0?tV$֢J(;fQ4ΤƪR;?-~6zE: p]b 4>I#!90R}JbI۰sɾI"G2$=sj9?kdsHCؗː[*ˍRp3r.|<>>%(;0#^g2Y|Ȭlcæʔ<}u ͏oQj..^\Ie+`=PŜBGQ7ϤU!OU\'_>9ػ/\·`$ks6.#ʚA)4C$gQ`s0C2,4ql9q8e&o].5 f(-8$ / {'r8k-Og)_kr,vXȡ^#O T]x]Y|ҵLͅ'K,//wͧ4GRyΝ[>YslYTZߟ9\]l ,;m!<].1 'DPQ$s2 C: X%Xply/sm6ZhV!ZzKC2e>QCGA媸qqFE)h%,&Q4$AI'B$w ޘDг*֙(ȷ,0me:^K m''bH)"1izen)GU4lVA9֍j29Fs0ȢO׍EIrv?9^.e7Dr\O>L//Gl㳡 :ŢEbpuY9gA\9NR8c ի&8XM~{|vUÒ78U=aVE'ip)˹Ӎ9^lʲ ]5kϦrH qeӠsņk\8ƿI#uAq=  '~16GއN`qz;s Nɐlvxmc&.' 7&Yxq*J&a灋MNj\Tyٲ2ɸ`2U5j@ג_||̊{>r W2a@D;ePQDs!3LX-ɵ6R ǍP){.7%ׂN_8D, -Jp,Jh"׆2u1et|UǤJxu5fh_0ϲ~EF\r_> Ѐ\=(9'9Z.cEg8)gO~Y Jpgփ1:8V4eG]Vk#ڝ!P5A=yJaYq@jdsȷUSnRfJl\(}`к]XZA&]D0\!2d7_xEQ'`{{׷F k-NYbRJLg7|{{}WqRE8Vvwޫgiik?z u$B&vĒÿ~ 5ɜO^x*"-%rx@j &b*k&c|xG_Uޱ`}ҰZr*ąx i)^v0sJ는1fseu9Sqy+ !eųx,bi*}t:tRZ7X\li#;)a(nBcU.4UZ xWaφH\}.^X|r?F:>*q;1>Y^΍zn]VAMM~^rq}2V\|%:`qYXz|-u!%V~r=Lj !=Iy3lb8t萯1z(LX V%g>4P2]j9gSu@Gk7wT(( ܾ}Ӽxz/4 =$J #k&:b#F*V.X6ZGeI'_W^>Rߣ$0P5ʏGe&/rlvع S_voO2S0ޑzfyއ̲ǵ:M9ԟ6#.w^1t5Vc3)u( Z +ۻ6U^wrCs(+B(ӀsUϝE~d^:C{ b,4\'9\43m5 XI#<}PΙ-A|qtivzf,,#o!8Ykrijx\.2Y|$L)SppflR(YlΙ|@ 9i<;J|ʆ5ܐ!aǞ0k74d"}HՅ>OoQ`eF&:gfU F1PX4(Dy]T\>#'>6ز7 '{$ sXuVzc ly_GߓIs+M)a8h߸^٨KY3IPR҆Rl!I%$x.KX6`I'9?,$0`uݗ"%AY2idy Gٹi&XJÂeV NSO YWʐMǟAeIN3>|9?g"uH-標"vH,U%˅Wb#ar҉XʚcdfR|>&:ýzyGu>pM!u􉇔Ԗd+P:'np9q(EQ`~(63%8c CX4a›xn}͑zFȗF?6X1Ž|F5K,Y6'e@r>kh $> WeDʗũ1&\X(c.vd{[5{;8uYX2>5$l!2tĚC⹇ߛE!IʍS)5gn0Y\K$愮h}?D{tzEHQ\>z_o%n׮ xx`b[$kC)ms_ 䶠)܉B6^geX9gF2Æ`wχ9TKƚiث|e}4⹃zF"#Bʅ%L@Z e9RG]5E&h',bqdDT$CxY*Z1.NսkLb2YpZת]bֿK8FddXe0ǵ8簾.Vf.b?l#ek5D "nYR63!2C x<9<|Z%@!fiD0]L |xI.%0DZ8p=t:.Mvqco>n[q6:ϡÕo?r']o~|WW+R>"o̸0Ho7&+=5ۊ7c@ձgE) y aڃw&Z1ʐ|j^R~>y,PHLA,1f(yg%{)"D O'uAs>nLO _I 8CKxrqY9P58Ye5t|+.2i|d\J=sR_~DFEaq>w]`|gϠDcēOX9LW\a=PMca"ތ(n`<?8i AL{}ٜ{UUʅ3w_Gn1wJ'ZdY,8ș |&b->vc3f}z vn7>$S3!Wvasw̵o\@c8؁1}އ^]|#7U(&nݼGnxݗ}sO]66wZW:'WKN ct"Ñ;c8lN|J=hvm0//+x}ո uFZO=F7o ~s_x іM[T%g&06>llAF5sS8"[kۄEڷ K[ Ͱ?=4۸o!CLK$c󗮯(YY^ _^ϭXk6H L/"!*z},f|Za,.10UΕŅ J,_=z%e,v<_@z\; r|ѡ. f}F:bv9h(MΞ 5Xdȱ `iD9q:,΢ 8e6{wgϤ&Waeڈ-c#gXy׷Wn@kG0Qf@{*5&A뎇F2s`iB94C\/@Hʑ , ֜ѯ=é2b+A?~Kx1nס+/}gҥVi1Rdݑ[ +E X3R(.%OQGssg#B$r y[?[p'[x#[u;w0w"i}١(c7}&hfsh-ЗR{a  |%0tЁMM,<7tY 9҈iTisyCu!LgUke9j&EQT̜Vk;mUS#_~st Y8?\%7= =xBIA/qassC`E%}ؔ |L:oL?CYd`-1x,q96>n%Q%S`1Z= #EO8ά6N,.o&"2(:xc)nֱܹc h,EvqW"N%JLP+9}[ON$ob+/g*67dLEQ`iIg%)Kxc tp{6Sv]9!p8Evb|?=t(͢ 1N%u: E>X0$3䰞cZX즵ճ)PKI̖cvq{J̖sՇ?y}(uǣd? +c7jEE0diHY(iFXsQ 5ǹ$mX,hh63ko.// ޜ6గ2pj8^{:q#}g_Hu|mIȮ,e9HKEN$8:wz)>j6wH6PoWq5r1>t\aw'=v<5sT/YR Xl'Yd_(n`U<ϕYd Yd_,%?z#3G0U"5< 1qzZ,j%pvpR4淓,W)yvd惃v1*{˂GByK (:Tuj|Ě)ʔo>LǎdΤ U,lw5:k4_{-=";?$l9ᣥ2*qW[ĜʅAKe0Y9-.ځSj/\v2̩qust(fe0de<^ > B,q&(^?XЌ(őR  i&\K'r5rDՄ_dH相q}^}xߺ6GF(' :VҔq_1M©*pLt @73>UhH_9DXpx;Ǟ](tV5/tyVv{( 1?,c *({}@%Y$Ӈ{FH; Ę {L"O]Z jQ1V{z=\^g峬cZO 7u$F&f7a9c5ș2+x/x9;" lUkɰ1\ZBk6sccת}0T87BfR̤2Y?E 1>.(Vk2ZIPZ} &Kp)a`Dгu3GgQ)uocʬ@uk!9ɠj$2):@`ڥt('gcA< (ƻү3+JR(7s%ſW^gQ['O碜 W xo➟($m |aQj5aى~nctܨ='WaVtK($VxH#;+:h|nd$X.%-8[$cйUQS&U.^QjOZH\Ly~eeiO1$δʬ(8`rڥQSӟ1+xfR?(,qeȊfm՚{& H{9|=3>8; ڲAhъtxxsЊ(2b}ĕYfIy1[krdH lI3bWf2<뾟h'n5٦2ljWfqD)`km*H $J!NsMn!_YuRo$1KM*q1r1B6O뭵)Z ͅi@o&WQK'sZ[K3fB^9X֚-r}Ҕ(G6 A~ ѓUu%/l,9(?Џ^0{V|Ԥk`lshծԟXsri9s*5g Maf%@}Oi>᦭CMŶ,Y\X46(&kđI܏$x*qΆBύƇ g{&lhl͜dilt.ثrLГce2a.R5ͪ*WC1w0ZPÎzLT\£&4Ѡ22_,*&{øՙrN zオVC=;'No=)?/n1<]VQjN6BczB;^Ff9oB<(yMU5ӱBx={1)CM'ePΥ~ed{m4@;<sHv 5 ęiB$c@ ߭(3Eh)η|+צ]E  {r6.PiXִK%ޕa@ Ъ]%ީP{JF_٫ϧ:/2.Aì_`?Ӳ}8(g)}T(3Cps.NY%1з`4L 35LퟶљSl[.RzB=ĒloYP3-h TQgi10e:oQf~8{ek8}&UjFiG-/Cl1TN%b]g_'hef`A$9vd8Я8_R&OM$}&6;2o"k<x{ϗr?S .ť%yXqę8Ϣ_;.r!Rg<|"lDC@A{"Rh웩C6&1qHIQ/UCf~-M%TZcUVc=CTrJ?6\j|gcd7}_Kd ]mfi ؕkML,rlb74rπ+׀iSA|Rsxi7_.|.D(3Cw9P:V5lBʹ@6<0|1}huj{`v?IENDB`admin/assets/img/facebook-color-icon.svg000064400000001673150515074560014265 0ustar00 admin/assets/img/fb-icon.svg000064400000002063150515074560011761 0ustar00 admin/assets/img/uncanny-automator-logo.png000064400000022756150515074560015066 0ustar00PNG  IHDR>hkZPLTEKGTNOYjj}&*J&(D (=.3K'@DNbMQ`"D";"@48U5*4@#>="?07J2;[MOW!=#,F&@'.G2=T9!=?H\".I*(F&C(:Z|dq*))(~)c+y&x4('*-9V$2qlXm+6P)2JrEʐ]%.Dъze#,; '7>/wiՄа͜a:X`4`&˜ɑڼ~oŤĠF8觾ƌan~7CXTDO}uzkKVgle=K^FO]aQLĆQwZMկZ˛2J?5eXץe(XtRNS     #%",(/)?)iH8vxUԮ5(u=`d8}2_Çfȅ>Jă<ώ0\r9 NRat<ڱ2zхڇlF]t*!IuAEtaCTc̽D_ åH 'lF]xյ}dWt7װ5ӛcfcX7ՒbsѵI-+,0Bb,x=Uq0¾ M72x U7CH!nw>4':}C͙6E8QSkDj N8\54I3XcRmF1ښm".mc.Pъℳ#OE}B8sϻ/HC˔I) yh%$u;3e=>@3F)G-Bڛ7oFC2[ݰ>|:Qt-1F5ċFa}X:VJ6ɢrX|_.?TJ %ѠHMbkZ$-'K$>3' b Kw!02]R5cǜH:Co]E.$R5v-">R|EDž4l<) co+/KCbtfZ`eY LwK+t-2(ea^6OV־9LV`2I9=Cg;޾Yjl 358%w-p`fQc#MoN=f,fI2 %㿙_}tQ6YG )XjBrw<X/]YƜKƙ@M˯,8|VPQ;y0TMW?,-\ SnA};0fMⱶ.J,黾h TR۷w;Vm% :[#=3LCc? l!N aGfuڳis|1_!MZwC@miU[q3pwwP+# @J5`@XZܱ޿0aܹ!` io2ؿ\*|X!˦@Y_ieү80b(1ʼڃx+~ϑ:->>oIվ.B<*-oH< [gzyfY=.8*ޜrFZӠ֧nBG Yj:fe.~¼h@}q{ZnZ\' Z="(K6kdU}{/lQt'9%^g '\w{] #=;' G=F*#c,aK*Qs[{_`_;[Yv}_+aۣ5 }ՒvfE8{] bZTý˗:I; nZYޠ3 2>XDl1[+>RNҁT*mZ_KݸX)Cѡ|hmJv"_mbapO<{.*H}<6hc*hS8;2_o~7}YpGZjiL2վYbu:6}yñٺe} lr{@'c&egŽ큰1lz8rHT>|X{gh%Q ?m ]dq}G-S(%WM~E{@Ww_cBB}c:1Uw"O#Oarm9wW {Br>Swn1mqӞtq>D1Dqa4јh|8hke^6{r(l0 lL]M4^|;aaU1O~Z&g}02ؔˡi+K%Ms 1?k;~z|죆21>Xe@/L\}p9Ο o3_JLU&|q yE^(yثgN1kJd@waYQN$ucPG3%1o ea)39^yWd 4y8JaaܧRr9yx#`T֒z~ {r3U ?tdJ6'cwEB~@ ĺok.UѵO#^w_2{G?gr#*ev5xO^~]L{ fFSu"PX)z>N| } ȼRwPle](T:gHCe$X^YjvnE; 0n0'U;)œ&&j 8[n4 V@*|edd .Tл0o t<4m$ iZAws|-@pyk)N Xj G2E^!Ep$Z>75ݾ^XxQm>Ƀ}FlSgYbU<7 IR`lqU{8مPZKf9Ը"ajk9 y/Ův >M1F[7?V#;}}u6\hr&f(^)QB1m¹*ns+3h馨%Hmá87ϞD@%Bns+H-a)A__*yŏPbI~ȼժt |ɛG?uWмH]T_gj7қFqӽŴ |5>,p`ZTP{m i}-17G8z?rС#߸[Wi)PMu(nڕ[e_/ ?LzI~y-^d݋Ӊj'_}#ol-.} {# k)'<&J[{֎^VUwsB!'.ض>(]>mzW/hjFGW43ƈ/op>IhX^㶟.a۱cCgcOD㓪yŻXG6b`(/a9NGGgϯҖ3B9*:;&;V4%XoOn;H|v^/;d47OO_93=6_3slra?J;u6VLvtJA 2!=^ ch@JI r/S7cݎ+tA9Oƺ"kCX"O`>zޗ_K%|#fh =##IH,ﰙ1?!6B[;ijzVf_33+=ܺx tL 淃Pe gjP~,v99ƨqlz6e~$AeszJ#'E"bsGr:?p_ yJCݼEW*Z((g|)H$ڙv6u Z^? Rxyz:$ 2LQ,߾݄\mmm w7}JNH>bm}ejpwlhE<\ ?ãVG73dLJ Nl!6i|r}w=ai*>Q_NI!,e(2JٷvHe|(N*/;=W$W9i= ~ZAg鍀/;wRFJ>RC"y܈C;ug4B? Ҋ1$h jo! .;6z^w2EM3w޷9tNS8uãj_zԻ{_wM,KeGgq30>x)paM;o01س;mX"yލϦfнsƀ3S6 rڄo Ӌup8z7'CW[:e2OJAr^ъ?ֿr\o Ms’=s31<Ϥ=ϻ0 LܭrdYvdwڇ0_RJ?7M>oc/zRi.s3 GGί>#7#柿绥z$/ #W[AN\h!&|KE4R0O؇n+Xo>`8 {jvbZiI}_. 5dԼ_⋯yR,JA[ᓳ菏NQz`dl5O7Kb՜ӡ=1zyz9_>@`G/Z~q8*A| 7`+C[*?J07|XR0,溲JI>(aV>T/:%h`<Q#||X|C/Sfcf\:w5ء pt6bhϯht´M~t9>@ a?3"&^?{.ouBcWI9-67Cg:yVeYkgjWDe]\(pVuKEmLGl~N _RGUu%?t Vd/P]qep ;aDa@A1=zsr }^+0JI}'.RL ˆAW6G-B|o]ku:߇բo@p.^ĺ할=n؁dY{|&jv?IG-8_ܝ]0׶l Doz|C)M|μCws޳y/?$/}{C 8cscv\{NnYKBO$%O@ם܆D@$@ED0nnmbCf#s/q۱RQB/O>B;UpGêCv{wnowweǭ^zS!5(1wcuCZ(VVftL3 JbTHpi@q&͞{GykL1C:O>8_4{ vD1pFXv?^Χ8KqN ”A4*nn<:R6:k\#>q`=EWe\8v(qY]!9sc\\13t Z ]%$uM2LdS..c XKgH&mBli9+Ad7z xrnq]R =}ש[H ~0"Tz )=r<&@T nFb/WA/5״& 3yn,K!# qcgt:NgRλd׆q-ov|e=Qumn:Mב~DYD@hNuwzIB`}" Ρt(FE>&@X$:8c]n R.Qqe;!5q.#KbhϥMy 7ᄡړhC`",11*Ztq-1+'S.\\5k| ^#{n4@T!~m%3u0Bp*e #P&63.N|[Mis(ZgAs7p T%},4B41b&=#]+!XͿ=司zT̤UL,G6*GNB!I3^)pc;PO\m8YF҃ 3Wوeӊ3e& @m7/BF]>Lr Yg֕ qL%eRNbuVCDřb0ZPՎx(PԾ6 )FF ܒ偣똤%t vc:{S /![hY헌x3╎yBĜs1GYmH:TcT^GIG7@NZ:rM"GFv\ƶh Yv.| U "#5 (@8>9XbXcAΣ+s郔{=#粥[ʲШRibΆ7i١rMgzsU5, UԶy4Bi[X!OÇ)_'v!"lUiDaW@_}K9Ҵ`B:GQEeݟW*?'M^YATƌ1M|voaQ ^bcz> zӢ9)I Bǔ |ݯt,hvR~-[i/hRl$&3Kx%I#x#< admin/assets/img/fb-icon.png000064400000000737150515074560011754 0ustar00PNG  IHDRJJ+2CPLTE9V/N4Rh~Oh-L5Su}1OFa6Tax8UC_'GӃpJfߺ٢̛Ȕďy[sٵ֪ljRke" IDATXIo0aCSb}+JQC sã`8b~3w0 vra8_,W`LOPx H@E!PQ*%dMFa'YʅS3LpFeιI1<AɧNzјڲȡ ۴Dr;i;RX־^>IFg2jԐQkMF!u[i_Jm޹U>Fx[ֻ Ḷ>b)NIENDB`admin/assets/img/oembeds-image-1@2x.png000064400000232050150515074560013640 0ustar00PNG  IHDRlف pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F)SIDATx}]uBB ?.?}RsC͕JrQc(\L6H7BII{B {4QM-4!x0`{f2 ^{g}y}֒f>kzkBxzzzzzzzzzzzzv^Ft`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`t`l'i-tkKI]k暭[n`Yu԰l-ۓۤmHou {ϯ)fYYk)۠xo_?ݶZƾgA{߿o5\S `+Z,) _[n?JG㸝ǓE_/v;di;z0 ˏ_ٝ~?`f>h\HV-pcIWNa+ᴜy?,}X/LNz", }?kHѶYL)NC;QlfvPK?ʱ?-)r)n߿g VR>dm|pSH:UHѳ]FO:㧽2?e~uNs}Βqў]FeĿ'uVNTJaӨ5KШ]Ym X<|Sθpviý@U-k%/flGm^ϭw ;ce5E}?bQOrzbg-GU:+K@fÿzE=a+#1uS~g|,gE{tV+V _f'a6ZrޝrAjG6[25IeKgHP޿K,r^9iGo_;­o#wʻDj:PnYNqgy35җJ:;zY؇^:#&nJa΂[xi9c[J),XΛ~n9jg>uKJ)aA"S{f߿[1HU cV]le^V6Eb־ڲ-?܏KI?)֩g,hal nkZAv11i[žKx9ܶӶcz}|_i|__UXheVHv߿k=|ZmzݮTظ }4ߦ HuCHØr->2w.KqMhbUjj׭;}LtQ;@>[{j)ЖG{M; AvRz|[&K6̕p?Kk&~4m( Wi?>*wpĥv^֖IK$v{xJ‘Wzm Lv䖳a{&TEj;Xv`QqK^;!G?'18}H߿g~SOv?͝*9oe|'~6>~1xzzzzV7ϟ7޾/U }7|KO } ; r.1isrrAo}P+Eٝ911eEgm9E-v?|[gwCO|WN}x5OOOӧ`o Ĥ2%Zŵ>>>q?tݝS_*svvNHa\$H?K鹰pIng06vo3OOOnωAX+6Yg5\QyO>uxmf6pyzzV!sO}K")qq*mZ&I7<=Xf6~!OvcNV>xWشe{?|PaӖ?}ΎƇ~o³h[I$׻9F:yzGI;dشe{OPiiow_|UahU VRa+c: gAO>l}o?}Ζa`ۺu븓|lݴe{G+?zk5Xwnqю0 HbR%MGbj16OM[wSl׭ޕ;V=lll>_s``{}nD$hI_*)YS 2V%6zFO쯳ѱe9<^Y_OW_;=wTa H<=[l*|v=tGDREK"ۦ}'Ѧc Mk*+]k `{ViZށ<|-w}xiv`l_TNP,Nۿw`~?1xXO[%MG,m4N}s`lN>Ndϊuj֠6?|#)agK<=[lu׀{:mkDF{}W[l#`;MIa6Oan'%]vz`0<|-7;===k}l׹=l0'J)爛*otFn:B5Tr%RY$o |pg['[g?P:m@ @786O6I;z5`í텴ﳋ?,-]]3SԸg \ S'Z4:|ϒZϔ52쳩ccb+ \al-iN]Z'ξ&["vBee}#d`\b qXb=lR?gg`賤ڈI)-|}cm?>q@O6O0͝Vy;cVlR73Zڮ,FUJap3^6O6I;pJF“/#O?Y6SafC_DzzvQ6 wj-?Nu78j+soTrFR?Dl7XQ `;?q';᣹Nn?=0{PyiK"Nkxށӳu[ߛo<"n;+N펪,yK;M ڦe)J[ggԠwBVո?v'1\/m(lJV<=o:Iν17No]u{/޹V2/*K$uUI-49FO[(WبvюuP;=0; ;Eғ|WN9yz^m=7ɾ8]"%Ho%6AuZ]l9zJvںvr?z;dvv}+q'ғB ?|6P/{٦bot~㞏:+ |* lxIJ%ӳ yǝ][r6 gT]ZJ ?_$7|ە6^]HɄD`Y|0sکq}k6OOegbき㮳pTtZ%V29`FK"{{{MG<==ܦtMh?n_I`V(YI]aJ"q$w`J"9*MeÂSM7NY6'Vظ86OOOOϫJ}lTɒHVRH߁ BRk =l<===bWܸaڕs5TeX胳=====I6$ҍG<===^,RVY ,-_8OOOO++gLa9Fr6?V#1 \!ʆ/{I'6*;Mr6xHMWwt`x-5(tuӁZ݇װ+d-fskgL #!<====5`8Er-^6NV"%3h$g``mq NQ8P/\ <====9`&#́3f:Bm1t4Dzzzzzb`k|.;yzzzzD5nxvLGHiq&$a=l7`S龒SPl%ӓ62jMH$aӁͪqRgk)%l$YQ\DzzzzzZ+p`%qҢ鈧gLa3hwӁ͚1u }?6OOOOOa%04æ#kl4_dR6OOOOO ;yzzzzDJòSdeqFA-Ft¼pqqeto;OOOɩg/yk`QHT%R*c83.-.p`t:D NMMҘђH:43N6a`5RI66 lrH o¦ǬF6ڷ<<<<μ56+0[Hu%Sdx<<<<ب;$.v歡SgC\"tpNyBPWHkMa3DCli'7sЁÁ z8;6aЀMrԜ!$2.Ľk T3o  lHnh434K"=<<<<4`v- j|Y_k}^z}Nmm܆S޲ ujY޿m̽o}(o3[g->klm\і{Wج\IfaZ(]"=<<<<$` \H9MrS )1hl X!z] -`y]e[+' b s{NW '4H(Fpf#1`;^amDZRy,rE!98Y,jQ²E%n I2بFysV9&TMjسʒl8u T5u;(U-zXS;b-`bp{_,vPtRzG" %'EᲨֲY'ީ^l)\gT)Qo%\$V`[hl()SS@Z2i9/bcY/ާ|Vql1^V[mXvl|I!{zz￶SK"ccJ5GXO٩\z[]4 vkhvo #I u%)lTpnlyxxxxP`!9N( n=zFo>˿+&U ֤9ҕFTNS<<<<hY$ӑɅBF7\uvЯ6*q߬N5 ,y!BUK"lIa H:,SKEYpPp//I l-j?\)\倍ذl7ЀSӨ.25wIyJv;?wxzpd+oyme׺]_uyun}+١lפm;;bNl>7lҪmVœf:R9`ŀ{<<<<<, 6_6z N`;`l9(/l>X^P@=b@D HX1-0(APY!N@jYnczOdn׮`qee*98;f>MwC6~1\8SbR֨fa *I_ʚ65Pz{{k.\ sפapdX^^Ί~[lQx US YT666:lTe B,=<<<3sazf.jJf4 }WDb`n6OǁÁ ami*tXXoǺBiŐ d:B$H:-Tt$6Mktvvxd``pprrfҒ>MmYJ"lUظZPnI2%πۚq6n67fQ㑮PhhlF L-iQe`K2IlQSBUgK-郳=<<<|ok|Ct!QsÆfDrg `[ 憎3? %`gOt'Q53iV[LY` _glK?;j4熎%H:yxxXMJkZ+6mI=lCdHU-M[w}OޯM[@#@GυM[? \×[2{ C[#-Wiz<h__G 5MekW[OOԤ8&dJ[۝; ﱷuB[uOwb`i?֭[7spkw.f057t, pydrO[8vx;f RFJr*+ lnO|6ܶpO'I)G<nvwشe{ ?Pv>npx(S~rT/ 3G}0$ n l~pW <S|^R;` ˅m {5ԶœcӇWp}or0O{-l'xM))Ub=[9+ep`sw⋾t`˙-k ՕlVR{W w|tg?|0O@Ol !p;]ˡ6+5Saq*78;f)IGM[}p-޾_޹5f -y_s}Ar КǦ- Cãe?9~*ڭM[;E\ ?\`)t`aݶl-^(Se?Ⱦ:|4>;!``؈Y.Ymyy9,-- LFZY`u_ φ;>3;v<ᎏ |ត:gpGw?_{>pGw W{>C_zxʨkAgK"e)W$ǕXݠ >{sJhvJ2˖DAhbAϿp0r[osj7i /K*I4`v_\}OK%~`݅ fx^v7 1m ǽnz=|~ýc=r #*:|x{7=3nnvC:]/_ 5tDRVVWrUئ_}1|{V_{bg h0v╆l w|tgpGwm!dh_vG2``9X3Cm~ֿ8-%[ ` %fI,8'D z]/}`9X ᳣L̆{*:b~\ZLaΓk&_ZOXgpl)Q=׍;\mo@ŕr-ѡGÝ; O\p;,YI$<h VZ]/޵T`~pK_x{>^{bvGppLE joww8.ydjsyxx5 ظ9lRE_(r.JMG{j3_/ItY=pk秲޷2l(x.ڣb:`ul֘ gGYEz#ח{ l( ݻw߀6\,Hin$^剳‹c{>οL${>cGxK$V axf8رaPC݆^zxx4ؠFCˍ6 gKUv6#nplIs?vzf6/fehP# *@-O*Wk *4h ?P5xbNRld{V[)K箑wpzذ]æ#aKu,öZ' | Fo;/}FTypz`0+mExl +9yx$K mog*lwp"9EV4hxjs|1gPa;w'KjBYs|9 f~mMUzυ'?w%q hvb![7 ذ˃_ _txrsvmFv6J£ i8qId6KJVVar'%τX =g5g:2F$OG~v޴_qg"Ϝ P l!Le{>邋G ƥ*lʹJ")Q.CJkHU\"[ l80A徜e?F 0BJaEx)&Hl`xr%]M%]&)k9# G*l l=Oo=c-̧÷v;>cǎEgIǗ>pEm;vxر yuH_$7HU%+ s-l]"9e K-8?9~lβƽF=~d v@ g^[+Us94`k l3b}]#M%ўvRoBYWIa"pc)#8l>+wvsCrk.6,F%Yӄa9n68/Osf.kpL1pCY! tgُ/5.Of߄?8ЇR,6N3yu}}23l%<7xfiO ^l᳣oY(쁢yáG ; `6mG{@Mv8Ûz ޽q#R*[ ؤHPϾcGֻ67t,/9yxxh:AVI#D"TMazFׅv+m6C²@&3炼7&a,_+Wkq) ?uu-<];?ώ2)5$rzfgSSmB%4 شQ6 vrT8}f @%2Vz#RH\$s;a!!R<<<$`Ӭc,`ӁTi\88:A\][OoZP6<\90xrshv4Jc%cOG%̕ՆGáGs]g^?9~*[{Zu ێUFN^n¦}mNH`|#/^)=~<~6J£=fds˗6Pz{{۲e tU''}4RXiZ+6(Ӆz׾wL&D6[igs`ׇHHSzVF)GT)T8/Zj¹Sae~¿ 9`hN58-v l[lؤq6dszfV*A{ q~qhgϣ}YKlNaxV=_.n֨B4> lXA;Jx3nI_[8w*\^atlaѱpca̐z,?q*q6g83.ãlZ+I吒HWDrꚥ,ravXGUAM7 P`0LH9lBxV"zؾcG?F8GR-eZ=#gv{c{6|r~6??}W wj/o{:޿ w?u޿<<b=lRVDƄ"-\WH<66ZWjOz†5NaX6^`r =j\'l'ZXZ\\ SSQm_ 1·ˇ ߫-Dz۾lh_<+ePnl5YA 3fX)HʬІ:yxxxti傩cQ%r7`0۲e <6TƆwMmii4YX|`lXx_;wR\"JvĩBscOlʣ}*pE!s 8thx_>c{6pEyjbŸ0x80ia`.MbP%IؼãLy4`9l-[n-vP+MvWp57t,x%70Nl4655$˕7R bxl߆/_g1>:@e:DZ5 R[(lؠr7`HnAFWgQ->j9F$gK38*r2æTHUPE[JEǚG7[ #Dc$=VኁeY·c`@87mE9mw 6ÖLsu%,|]T56-]&qlOPŒHNZEtn6+$fH:+AI$h~kv lY4У}kpI$æs뼺޹4k*4>V'<<<6,: 秡UVb%Sxxxt3\-},%02vj+6(ܲe o2f))hকDZ_\\^.\ \ʥ[j{xxt)l4Ū$f\IT"]ahugfýlشe{شeH?/m/74<>{rOv.c¯z{شe{-koڲ=##OkhW4Xd7KQ٬ YEmHk >XfAɐi<<<lD6 {zzƉQ;r.1 SDz;nv6@55:|4@7 8Hï,;w>pQ6G /̮Fp}O75ج*r?qh`#†5_SR*J"U`nk1`Ӕ6K)| +lRHIUrpd>qn:ъ8thaӁf?|ugf3 厰GwOᮝ2XϧRFi}ʼf[g-t1E](B m6P@YöozجZqF#V_h`\3 Ύ%'6~tcXTlCãGÇ>|omᮝ O $ݟƓ ?P O.ܹ࡬Wu۶ۤ=thrj@ݓ ~⳦N̆gV?/{ ^];?i_ lσeÏ˶ g~rTM[v~*n-ޞ۾~v @>Y,1@ƒ_.kv˭*Q544Z M, ҼXKȮ]n 88]xK $mppc'Y;yxx4 IU6ip6U֨68[)k ؎?|^)Z;r{$@?Ⱦp˭gipeݶr8Ha9p-)րr2[nCãAw Ν۶ߝ=mm}ᠸ%hT藺3_ z{<7nCWn߇x(`{;fuܹ\?W  Ok -cԀ ?vhV )|^mקkhYT<k2,e~YYG0n/\zذņ#Һ$[^^.>󼸸XPجK XJd<<< lPA)1`jÆ$Encqׯ`Q 'pz@zgX83SY Q拹)v) r(@}>vn=`Y CEa@?=/K%3x(K)VT2 q|,`f-M,;YRRk BmHPzzzO1I6GͪQppq2,..&^(`6֌H}MBT4H,]"Z lp: 2K#"npXфfFhsbc=)hA~~C2~PH}OG?Lo- lTu AVgfs}O.F)fezƴ맦3Dj`>3q [ XMJR{xxxH+lFX3D9lZIdL]6zЙzH`E * )ĢT`oV`.x@ (lTlxdjbAZvf f-}.p̆C?q)YQbVV=+ t)ϧ=/V@YeXqpq2z5 ^ 6aVH628Y'$uIu/+8D`ZNE6 lfEc), w/^p ؤPk{M%A `bJ}S5@qUmϘ%~LҶf!|nrT8t]Q5$Rik,@dFaåroou6iR$.s%Y8Nh;}<<<<,aঝk4ż28k5HNi[=lWMD*b`Fr8 h?. Wj83sͱAشIAZm*nNs/ ?Uܸ~8xN ?9~J\wRmwf/V3  ! NQs5>NU?ʪ. qRF-~NZP 6aqr`a*x 6tD:xIQ0f"֡Vn`"SS6im,#3*1Zu:Aomrώ~5SLhYp6jv1=3J`{m۶2#8 vP`Yl{ƬaYzzv߰Ϗl-kO`/>w~ڭ;fMUyy3ᮝR+ltk>{u4MlF}F@5HF+lrzM@RK$5Y Æհ6ZBP6Ief|2.ieUM>` nfU8'5UشaU3 ?v lv &p2`Q)}O˽k؃sj N)ց.3fm-v3v[𲱉SN h g)J~gV>*mCpa֝hߣz^C{,jHԒC|kђHPvu#.%zUC j hrV*jU,"eYg=<<֧–b6h#'IRY`ӆgWxx4|}G'?fQQ%8t(<8}}YLچGŅ9-Ν=wخ_`^,۲cޱu ~\J{/BS  ?)H7 bJYEJt=^G"͛oܵk׍)%@}ج }>;20f5C6t6-5cH_szѺHP!H1QY\e{4شtoz c荄OOLdd7YJ"ppMG8`A2c J' <<<ؠ$Rol1[p+J"5Mڀl6?lP[Oɫ[cLG(U˨4̈́KtfPk׮{g_o)JvM]2)sbmjMako|81XpƕH_28۪I3u`hT ؠң}ZdirSYeem޼F mnkVX,f+ eKd9l=`K1 #0:m#:yxx3~<.c/ԫ8 ]Dap=l`_FaKY_o.4Ζ5}f.N&/t]=F/,ӳ3`$ N^Y[ l\/6D2Ilh)u`Xa9(/O)0DX,f 袷Qt2H k7ogKm]w Цhvc ?>v27?~#ډ,-qu?>v,|tٞ MQ5sp6.Q{I|<$hs`Yʔ1Q걹oF9uy⧧^޽{ g _H6< cp>(}&DZ`{hxHX?Xrt|}<==8z.INܐleBgS)Q5́ãjfU´34RMDRd%J!lRId 9nPqq1Ű6Pb!04<*^0)s)]==Sa5,`l\5 *aZ$u _v`iI*[#7 hYS5K3wޝڵFp${{{f}.}8xV5|6:M1̑SҴ-{Ԁ!ӁH6lX6B\"f GU6 51ܴ(UCێ;޵k׮hT]ve&$;vxÖ cЉ# nX[\\ +E:[0RcӠ.KSR'===R6f#6f̓#T$2ѩZ:yxxTRKSMR0|S`C(͛76o|#\.)H=0JANE ;E.,\*>CgM꘵Dal+ԌF8SW<= l> JOU5ںUɒH g\dlhGAK(,~o,ã$%;М8^~-l`zUIg[Gw[LkT,2t6LRI6Vl_==N},@Xq;_vp e~ctl7.kJ,?^V/T[Sz?qJ5>uH @LR-"$ã΢YdjF , M ,3rBq05P0,-- >qwo۶f0"yxlqQT >60);juk]F;Q `+;ΰ#\ubF+9yxx48ptz5Ҟ?Q/4JxOwx9mv3[oouj۶mHmv3aPìrMPa`0H^~np\dlόU-VTOe^b 6 LSdeMG0 FrH/hq}*];Ֆ;N61+upZ/b5 _XݾpT83'/7Y;o=_8o{o2qr`Xnz^5 (A =`^3Vlfm I yxxtI}).P8`G4ʺDR5^Yj垞<<<؎Lփ2P->Eq:?J`u5|= L‹?0u9i~.9p(:bŌr ˆۨ-D✟_.N 'TSSarr*ި){:6zز=W/K6 a/ab>ᄧs/ZӍ#5KXu쌴ze3' IÐB{0-,\aF?$8>.wagsѰ2q}mJ5Z1.--6^}DxW_;~|d~?>v27ex7v?uGݳss̐:MaLG$S4߀n(6fkBJO4ؓPTs+-oJ9CZH!1Mb s{O8¹S^ v5_ dnn.}r۾5DQp=۹06~!,,\bNkob P(|Gw}վ2s,'_ lICK"ef;6 Ů}cMY-e(6~Ml$K JU`-k{rF p+++zF6<m~~!0:6^p֬ TN -S.vRj)֌/q|d޷.Z5<<<3؁vi9 7b;9;æݽrJ&@ 'YO^xBXZZ sss9E Gvp/ͅ06~!/L%-4|xr'7ã6j:±XYdzESuC % v`޸˖z{$H=eVVGm!7@@9annN,pu` l'FcEe|7<<<:,}l\"9-V`ʍr;yxt7YMbO}2@K $H ,VҰ $/?SiX]B,W.)lXw_=ډ :L'}{xx/`kwf|8PeNe<<<Gl\XylҪXf2QPXt;wjYۄsawHˆaDB>g#(Zڲu추ᅦG{MrV53, ʿsبڦFH́ÁM;`k-CԦ*`s>)2(73 MH]\aP6 s@a7y)i~U@j>`'R{ؚa:b6ɀs 28$ʞ<<be܁[JIdeٹlSaRzsii]&7lA .|` 3l,ͦ.lV愃FN(ã3 ;w,6%R5]Sd鈦ie!-*]󤚏BSriTU『ip3غ+Đ F@]2 Ќr$`Khг>籓1~=<ƪ78ƑulEӆ>/Zl=5۟p* .ĽWP2 y\Ne&-`R2>~1\Bj@G*u->Iزi_` Ζ~UISdK$ιhl kDYƖ's[,T5?3ؑFAUVWlгlaR)l;ѱ ظJpg>2i}SxxxRMGFEiUذҦm$W<<<4n)zib-^[׸Gj0eخrNXelqۏFj#cCAN51:O* _{~ҵSjVԤ$#?62*[\ʌT@)fbjt|`Kmw_gC!<_tiЧF{fgF7j# /?`r:!FWÿ^M*5!ˁ8(h11 {< #A-14RɉHJ4 qVu`^Uj S֬=gY,Gr;Q: qI$ ^XsrșOnh~0==LT΅$ٿ[\m2׿[`1چGUpqc5(m5 p!BUA#E֩cj L+Qo ,6oahDYd>f,-uUJ-=lҠl$Sh̄OoN>Lm KKK9c6aP˩jv90C*S)weL2 TQ+TvHcMr咞M.|jeK"[lg]8kPUi+lE=K_=xʗRFg|5 tL4>Qm#fffMOOglذ)hkK l$EH%e[ܑu&EŌ 0wPv7[aN3ؔpIe1hwh%fOۑYz莑D5IÀS+PHcaR83gIvi|0W %P 9=}՘+l[ԠHC\/RX/P2 F2=m5g|tUCJ&m!IbWqЦiʚeڇ&-תT,-ꚦq6ȥ0?lt'C؉WHf+++633*kD6|y5nM2S8bA a@A Y(PT٬.2==HWk:BeZB+6I,ƒUNa$[j:yxtw33E%΁ lVu-6UFMG8H3,t*EH6YX٤cٟi+$+2(jE@\?>::?n3Lq5rH q8 ԷcZWHw/ Ÿ4ǍF  t#M*lQ8"CaGLM4-k T6Kko_Plz.{f.th;DX\\`mzz:LMMbӑ<kyh9rL mbN @%ym^k@[`k?l1zn$Ygs4H62ͪvJSq0qO9h msssk톶/ɩ0=}!rrr*PZ i0lQS Pcw-$EvEe I223ҍE l`$S pt$#\gYbZ*؅g6";Pl.B G$=f*S?\4F?055&&&2%mzz:LNNJ$ظlR!GQL}<<ShM>$[²pwZ\6Owh[vÆ[d,B7a8yxtw[Z9d\4d2vz)|q8 j4p 3`Nl>27tX65užrr*LNNe$oF]"uĉULBZа?(elg($3ífG{`oV3MK$'1ZU5W<%8n<q3٤JQ띋V*:Ow쒒ȔV8)awH- f=mseE,+-c8"kk(vlԠb)_m)n1-uT9Cr=k`rH %w1==F55Ma{C$Ts C?π Hb3pUClrGgm#9i7*qp6jLc`(gT K(8ibJO5wL,uMHp.XeJyxT,VPJk٣|1Xk&#! UXa呴$[C6^;5%'&&r#ϟJ(` 0|]A[_(#sy1~ JVxV+c_0NUS+kRs$`4jM%FK%P?קF"9jK<hI iLJD`'5Nm ^L][1 e#g) ϟ6?̰Jup6W#XF-szF3 lhIe l ~iuMZ6xYZ2|;Ml6aa)mR?[l<<֏sUXpkuv0==[hNOO=l.=JF"W G\$<Ag ¹#xRɤ:Jk-cgPj <ۀM+k lZU`%6"Cliҁã)[t?+YU8Jjek. ז{2AY$ș ^x/Mas50ئstFS$U0Q֮)0b5́1Ie DZj1ՌwI*gKas ;j`~Ta .Tu 56TRd j.1jRVaӶc641Aِn{l ap*w֕6v ̨&ۙtdvv. ` DI%XasrH3J"Y]-QklJ=hR/XҨ勱EmyŀMFt[\" V&խŁãsT6+YTjҐRG+YJ+%r;Cl4ݨX #p, 0tau oٹl;a3Іzr RJ35 C8G6_J8En~7MۯIZ7;6`[#en2v>kgC2aSݴkll1,2SfZkeEJFp吴[ȅKyBtMi$cHc5G`ak|+itNF{0Q%7lJhNRY Wze2F(5_,TTZxzߚ-Mi3;G*7A܁cZ , C }s1ͪMk6YQȥ\blл*\χ/?c'^ YI($ ǦeSSY\U%F %1 jl'8\2H5 l@@LG022AuĊ3 lW6$ nbs@?mt5m52s}`FBY%sA 2h 󨥏 mφB:/`YZv`+3$HNmqMz\>66CEUKF1 I6MqLF$TN.///F@/H aKwjF aQ`8 JP$[lK$C$k+/rِP0ɩXHM0& NZbK`jWe^ $.J%9&EJò})DS:(XW"gU!ג +kTqu +kH6;;aui``kR`867ܣ{ְ+\655~4Z,GK3e R0Vx8FaH6&9=2nPe[Xj^6D2-:BK!آ,l36֟ Pa0cel[i)l-!))N֑1jZ&YMp@# I +lXqT"%4m={….PwB\u6< .s}l,l*A"9 ~j_1/'9>քk5aQ>Xfuszz))ʚlFٕ6i&[L{{{s`XZPiˏ=eVRH Io6l<(hPK"qb#+k @U @vl6j$(lRBM{(ѹlЫZZ9$Uܶܬ6js\I#kJ2J!L@-6-bRSY% VEsXRHφ5+z{{D"CUl u` H66Tbf#s $LSbVxYLq2G,6:H;EچgBKc$ ejdd$x%}$ *@(.ťp=C9)\XgHI]+c#3ذJfLCevg:(Vvi:6 ֛Jet`Bv4-hDJF#hU [9 6 ;6s,@Vb2M*\!xI׃eaHVp_ i"AA C؈dll,;w%>+j๳att4av@8U7l™8)h?iJ 6 qvXi#mE QhdĘc VcY'Sdҳ1_>=l{PhFU$#T"cByJ[#v I1jDQ4X\6<(< 5|IBu;hx%~#kv_;JivIJe Y\. 5Qs0eK!sDHf&;$F)DS)w2Oڿ&WךzhN1iFQ`?gc)mlSi),3g%eƛRRۑqZVej:2Hl@K"1Ξ Xv+s\&9dFaSqi(Cq2g:{pO5ɩkJ$3 òQ9%j`1RMTȘd 4wG 9~ĒYǚ0a?]boihF5i?5]a,P83ZJ?VCrΘRX֜&H$T^Ba`Fo-2(Nܨ%Cgiܶs{ONQv$UVv~\ |B+lX}"k0*[pݎMH"\$6 aT.vyn41}pmn4YTakVHfq*WI6I^l<6*uU]Jid-R+ԌJT$V& S;\tPil6c'^2 >0|-x% =?-׻-16p np߹џ@^jV(qk9m)6rƔuťr,'&&rCY3 ;\Α a@밝6[ Y-H2lFgIp3%̜5j_bV)"5Mų26W< [+!c m$[JDbP?1IN-l nҙGT-^5Z7m8@7NMF4J"@rF!uCW3>~ /O)7?'Nzвyqh)$?J:bc`[`[(z٨4 5<S2HZ9{ I5ŜkP.O 5e7 CVkn;qR֟c =lj,lSiQ,lD^*kF"=G2b\psp38Vٸl1:FB?6"64$(pPxP;lgkOO{0qcdzcSPzP<33Fq#l7< mNOOJ"plQlϕFGHI1< v`M)}̩kcY"%,ɂ^mm]]~I$=i9iJ6lOAR% ͎G:yxtYgzb2Nt J"P7IIe`:¸Fb ΐUHg5f[(Z,-&$jꚫkLGZdž6SפRQ g&AGm12OQ-(l)עt '7 +nH9 ؉Dbpup& 6ni吠׎C/..J"?(i ]gk}iԐZ6s oaX._<~TNaӒ4ЛKZHMF\2''mۅc`hwnܠl0Ёz `H;x>U7Z GU0lQj e3{WGu6hYSJ0E( U6f_V4 8EV%9yxtFIdar3d2^ V!u6<pC6FMH5|=3Pp$MM50Vذb  vx~.y͛eͿ qY$4<[/PkXmaH /d.XU &a~aPB$_qV,6θSאZ' PU[fi/Z*l1HfTէP!j֭*BF΁ãs cֳe~2Һk_&Y[QU T4c'Vl\I{ذ`mRa855+ @-öye hhI$V8h˸ ^ g>@P@Q3q3רsF\%HIk#;@ .ˤ0-48> XOGꚧtZ L`.. 5Nt`,X.[{RLERzb/;W-RAiʚt4+j8Hи8Hi@>6 4lV{Ǹhnذd$51!@YTy :EV_[/a S$-\#F#9 C0,gO֨S$ u-RΨ*[RRrT PڒsO]]–ڿi F FBIMљfQ%0 }l4kx63 x.I\Ik25?j @ '5:G/c3(ix& n!_Sְv!s")mRk&ÐeE Ը`I/×p$ lcsؤI޿R 7!Sb-l nTXoYl)crG$zݤma !pg9< p RAa{aHDa(a`aCe lXUs$Glُ׋!q(ih}?4иIl㟩iP9Kˁ.}p1ch?WIgIτHIb[ JkqqB: ۙ!%C[KԿGšՖ [޵2p ׶W-iWfa[lU62I7 ڠ"mXIK n,`8(a mBEX_\‰5 g5~>ګF"[șP }Pn_ڴi/P Db@;i $mmULECΎll?RÆ z2U@bkZHHV=pItu8-0*0jJCf6-%O]b1Z<<گi1uM. \R$,;9ip'Anh9$]åx —.5ae۶m^ <.a'GPkN5]HozV( E,G%l Ɓ=I;W+Wdm-k134/lHIvR&qV5Fq<<:Ce]W. w)ŖhXIdl>.ӹk\0ў5*HTm[ZZ|C\~{O|/oڴmvdž ` bYk= \FRuxO?KǷt9}S2)xpbΏ ʛR[MF7rH6k9dlH)-V`"Sz\aH Y/iZ/SԶrz!:OZ"it6\AvPFI3ڰHl:rM7'Gr0 ;lՏCQ~߇UF pc?=G?w{}k{憾+=}aC_qkeŷ=Y[&5{\ ϵv6ڇV3 f{Ȅyjieռ,2:@E Zms*lR?mH/)lCrcg,.IKuz+i#HI}Ci?ǷCF  ;0^6AOm۶M6@(m2D1PK5-?.oeX-0U<6Xlۯً+b; +E!WouG _. ǖ;PX B4_k%1C{~f:lM*`bXH+t`RHreY 4NXb[b$RT"s#1QHaH|7,tP{WU/ Ss9`GH46Av'T15r+P.IeeQ`A"I)[*mg )@nC_eן eङ0=k kLQ`R yr=llRE`%-V G,dOOl큵2T|g]f1Aek[cp=džwTiRJDRpԘ tp- Vڠw 6<*2]'ܗGaMKC|㬢\N]ϗ*J 0AW7+dǬvD,`K*V -8K{缟-^uq ӑwp]1+u!)9yx,2掘 zZ xb ɈGSbô9.c%1 2\GƙrвDAaH\"9.΄eX5_ )-}qey/7Z|&܆zp?ZskW+7e@&X<_•Qyfմk禕NL*l҉E؜V(lq[g*][lGA N~/Me-v pe)}n 8FrIܫFA=bS(О5߅(Z†4By$.}et7^7\9? *0MIôaUmM+>4j, HrnGr6 q]kyjr UcRCJvs(g_cJDr&Yhbúãs V~-%)[jeY+ijt=7(e+?N:hk}l)@ @ņfg¹lp6ڎ;E z%rHj:B6JV2i _ rra@ƚa J5XG!aշ2|Uo,%4\5A5c) 8ͳ O8DZtAFT0qJxx,VH$c?1{pǔe2#!uI6iIV35Zfa-Gi)"\?:6Dر]!m׮]7tM-, i(%PwM6d:"9E{QoQr&$F"] FP[AY[b ڮIbr@V\իM׏ɖZ~k+L)l&`"ReiHܲX9q)3R{b^^B#F 0ż$:RXV} ;dY%gzt6Ne51<lum+9@"(1v?W,,[I@HIā)=e8ƟˋT׺Mꙶ(kæ Dv\6HRidooul/kPb?12jT>bRb0g1%RH;$8?^.NiÁp\aH2]vaP[lE*q@!\J"Y<BQrnxx#id8, ̼Fz֠ یQ5@RMCr}[foQRf9ys[K[K"{zzNc 0T֟+Fo$J^HKQ$I)uH,R{4-rI~܎T7İMR,Ή\I"+l HɁ!3:kŠ#7 +9le(L~ ?Q ֟wd"3s$݀K%`} uLS Vy:t6-] [ҷf:_ ]tã吩?1Ð=bh<Xe-ߦe8kR($?E:\ =l`4y-r7J& Ȧgu"(Ivc?T5呛G/lZw-_7'9sfӑ @}cդ:&eS@Ԅ21n8%VkVDƪltYӚјSGf+^ Ybd-LYXd%-wMSشGiYҙNSƕbє7N?=2@UՠD٠5ђ{S&~TiCJYm {P\%hߙ4dvc3pjRaH`8DM%:yxRS,dإH mfXkকCjA?w+m g2B"RJFQwE 6:a*m۶7o|#7)4<HJDD)ϩ[ukд|ps(abύ=fo~Gn`#=nJ(&:E*Ckd-rI}gE X+د6-Ze:"m)s,(BGk P4X\5E#P1!oH&)je0vtV˕HrQW]vݸ{6o|#(n7n|76QLa[\\:8CU-W+n{E#=W܌aa`X,J6,qu-6Л"krW{;0n_z[M%FK! $B$ G{!-ä-@e1kdJPYl%aIڷFk oT IetlP qw퍓C###l7gNj#uQ?B3ԨV0/@y(uwSְA g[/W(@D9YG l%&&wt`Kul%c/[vHӾۙ޶au_G?%^6FJb0Lű1UK) MNSY k}nZY$φU4NyT%NqF4GF FÛzi7[;vk˖-7PInܬ9- llh FfiDa^Uh$ S˘_@}RI1o5pIϥl]d_lY bgK\T UYer,ſGkaLYֱ[RYOieY%M:MQq0A*cT * ZJr .{lvJ$Hj" Vuxpʊ8#H+o{}hyk~<"ѡ~b?[AC!%`bfBJ#kZ"F{ʪqF\a[6 Ύ37Caگ-ڿ.ܠ:G-E= *uE=MUbw!R*ɹ@R#h?V0tI*V8Gɕpdf:ݻoH..N>IeÊ-t\9(gJ3ӑ~?g$ Ee~%I% bG p!ڵ ΒX %5죦'fYC=t[4%\Ub%ʶ܆9yx_a@J(pc^ት4#QjuymjO/NQb\_ xLaHĊdfBAZ)ltS2I&#Tm`{~q\u:;ܗqdgY5hO%B DG$RO[KNcg ζ+4شXW${Hgq%G`͢(-:MXZ@Xd b #eFdXQp$Xyt.NPqwoٲP٠#tIM˓psrLbh`kd]p<f.@dF졀/̀9EJ#+}yl5 c}i]l2%a\"%Ho%6I{״5ah-òH-[JU*[+ҟa ceJ4n~5/sKm|b$5<4EB]wlϏ |p+GU|1g*Bsf$Xm/+$7;gK 3ݎfm㕷 ~bk ՔAݪd̝.֛W< bU<6<2V!Xy`| `yX~Xc*X kɤu,RS,> V8 FԨDC>6Pvڕ+|2d"z֨[df:=j eb˛5+@Ga.2Z/:V )q9F2 |[{IRRZ UIô+[)*7w+ށãJ[2p=.u@^g)XmER`erJuyFPu 099N˻vi 6<*^p@GpF#lF$qQ Kr{keh Ib}ex4eJgs<3,j>5aH7q*ollVքYY"TtW)nA<<j1hYZz ̶QԭTǔ2в*z\?Vb>CFaEF4n7\f)lq7>6 %EZ)&àFa> k \ņ pOXǖ-b*XS`&v]0<X` 9>487J~3MQ4*YS88%aki8d6an+:yx4 `–2O%U9v_ @c4RQ׶BTIpU83؄3,Y^^slrÖ-[naٻwi ?U(R %lG:^3a%tPv?#?qJ+i\_$1SɴňU.Cd-f2"ȍ: [3J"%Hi0p{M7NYӌG<<_Ԓ2(gDZUŔA˨nZ d7DSB,3jOI\6F٠ q'k$b͔+DB[2-efՑQ%+Y!uK.mRSGbS HmQɁv ݻoظqAY(`@3ǩb1s<ʀeŰ%3$3)`|)al)$q,[_nyIG*KGTcKLfLSjb'T ҁ͓[ӑf*l1`AJ(l&9hg{xԴX)d2Vrبule4c)R3(=:q"+!&G6Ne۱cǻ@eFu֙G]&8ig% 71n rOQ3|)xHEq=f7p&#퀦>im%H)D=F%=l6,eX8Ҫ+iƕ?Jl6 *h#ԙn)re I*r$͒1\+rsK /\ oz;v zհφ]")\b0^tҞ7\:y%+#i|YqZauA`U=c]#҆U4fd YR41 LF4,86 l\oJ[3 TiH7h_dڬ꛵\2j]3 |Rb%ecf$\dp rlR߽{ 9ljuTaêDE?SI\$, e؈A`6 DP4cʬXybMY>-4jps`\&jՖzH78s$GHa5MR@]s`hfa]FJycZ<~ 6k))׭ݸܲv}8El96~ɭ^;n-$y FA#\O!ߧQ8HnX^GHb_CZ`*" fK" 0&9A,Rsl>$vr aWJ[? 郳=<ڣY,Z`,EJ),0 uv*a$MSҴlI՜i؅OO,)k15*9@ !ǖas(zӨvoV[;"1e5 aH%?k$kZYQBԁR٣8Sʌp`t[6 sp~\We9Hw<͢tYS $|%) ֖rFKZոhY%Ӛ upm׮]7belr5tB0s\^^._uoD a9 w 5ѡ eJ0Z<} qtMZP~XcK-phQ,6+ԣY.5xdlTe4-\^^H(ie,:k(Vظ^2Z*I]#xF|QEo#V,LnP܋J"SF+TrX@*Y L0VAh{[25[aC5tM$B]"2H q>66֗HZZLaj`Y.U-Kܩ&'@Nɖ|F{ݠm7P;;v {{{-Sr3t:Df#{0/G2F%P]1%{Bi$Z&YRY!MZYfp" Nu*YrO|prV+loH(τ*I>8cm֡1(ey)(A|2ZXV9+[Yo o\_ _6i%E-Pj&)%%k-r3L{Q8G/UԈ2HQac(ƫyW׫f)Xdžh3Ab%Z[OsJDZ+zUbNSr W ͦ+l j0 Y+{LUR5융õM_S̨ AJ{n2$ܪeQ:8ac{⮑\8 LIïsݓ/zٮ{ES>3m.e1jEϠuS,6W6$HO9ַՎJ-lqǔ2ccU8@Zg]2e h͎`` zz{{\"caX$u6pQmd(۝"8ⵟg72š6pگ8î+LuYfQRj-gr)jV-UJ),mQod˱9l'~zeN]߆gk2@:a %EP#U`G樱&%G^byhL# X,YHsڲ|a$8tF"-]cx,'SqHauErRHR% hցԍRʔIZ;SU2W)&* [+{7v]v݈{հ†]#fgUc%g@jM~ &"9symRKmo71m DgטrI KԒG6ӍGPQmeePܔvZb3VDh?Æ_xLtHYg5ӤrRJ'R81V,嬠4u{X.uY#P+Yă9f e<3ɀhOQI}nG͑/怏1 &REMY302ys`V8E:HǖEXiV:2[sg3M*8'U*l1ivn:љ ACI)l˱ƲeeAu(PeJ,#$( GPh_ۙޞ>nqpF [f:r0gmU2(JaK0 ̵kp%9 klZȀX6)4M(4l f#n}lUWpmh)8' ggr=lqΐh]nfQe2{́c}DռêYT;V QmRf\@=.VL#qݻw#eRZOaWJ"!{.s&!XQ+a+o8lfR}g>O-oT45 9\:_}vD,tpvp233H )UAgִHnZ $́ã*[LJ)AJ@e`O}-=j10m@%mUIc= ƃ?Vٰ!t qjQ˗&/}^! Ua9{ptD5 a2@4SV8,|m$ acM,ô^ch9@78[SbF$VaZos` MD RRi}j)=wh)L5HXe EmAɩlp6Uvu#?008%)6in=s Wr-S,$渗/c̻M2 w8ãLd4 S:SSSfU5k6Y)}7O?V4-u`vK&U\I$)](ej8 MS=sGXK%dE# 9ŭ*^\yIeO>*AƜ";. Amf$4xdvv.6\ z`k$@[|lXxxtfL+&ZJc'=8)v)2D4u=YO eYu҄:0%+fy܏0p9o:_Wf]f>#uυcyo(H"`.78[(]+6v9<Ԟ3VyŅU6S>~ub* cc%JPq噉db$ڀmnv78;l᱾"SS4ue{R3-`Qb R-e{I}e: " lTM×'9lkj8|7y8/A ,4$w}_?Vg*hE.I ULi [O/\f&a[\\ r5f=t[ij<8m֭/lt .LGbdI_+l k)StZژ w͢iV2e\8󚝱aSH0F#===o޼]vH6l֪fPAYI$u{d\#YgFcQc>P>)񥕴 ]ŕѬF0ýk};E#,r}Br_>ڟ襬 ` D:1.=90-Xa8<9(5 B3Qh6ѹ +X, +K ^SG UʎOƶڬ it6S8ۓSa.J$sXjbFFr'_aڑbߚtRZn7V-΍f}nXceo+u6X[YYY0CP&Ia_ M542bp6i^\YJ[ ,V@R +H1@]*6c`w'mؙ68 gG͛oD6j;zפ78RDƺVAJA] Zs"ȕ?rJSeSpmQä46O_eV  %I199eK#)i~TB]"%xB@K)Wu~% XVfZAn(`WHZw``ppjjaZ̛m))_jyPʃVWf$zA޴*oUi(6lݧ0+,^,9Ϗ^ʮ^]w;Ij*vL#ڡ=ltaX_f-AոnVpJTAa2FiR=& Ti8vkcc$԰[$-D1c}řhs%9#oV" VFpZ%+jL4=0y a6EvcI/×p380-ؐC-*udYG5ץG-Vvh S3Z[O c@+, %,UK)LI#l $zؚ\)$v*[ap65 {6eL p6p;es^ɚ0k,6eF[bbg`OG?oAJ*?B8]QZ/_ TɕAb-|&ѣT)ѨG{5 ZjZaQʌHUᬃ-&)eԶzT!k b*cmp6x[lz,e;f-9=2 V)N54eXR>~&f/kmsW^5r(.=ObMfЬHJIyxt.iN ZѬF$jQTYj +[aȺm0NDf9`Qs 9l~7K^[w?rqͣMi<>9ʬ~,纔ayڶ^K=^ :F#l\ 7Wwȓ-]o$\?lSvHn=w,Xo4',P7{ e{,Ȳ,%, NR:X8Æ qi$fako[^^~2pp_#-W{[-AlcrAWzzvJJ-BR] ?T1;; lkf[}kKqt` e29eV|YIʲˊ=T\գ5B+8rpq2>3xA9بKdHpj\\\QZ^^. $<IbdtB&}^[u/Zǭc}U?v maR sssaff&,{ Gl/_%͟Ɯ ب†o:E:yxR-SbbsʥVVg5DBpZ ~.1,; p\¹DZ>s(\)rXen@xsYz {ru%݆zK덟/ /wp#->ޛ{fY&w-'{-{.zH'QϸYnm{p5L-_ І{@mbR&v[o2%܁ã3i@Y;OJ]e]ciKog䷀N#hK橷^n׮]7rf#Ctpv#G4 p5&^u:jKpk=l/ $`:XL9P*hI+$J*ɌV䅴ാV ϲ\Si͵]]-g:r⿅қ[++`i㾶I28[*49yxtʖY@'DUeIfU&UTFqŒ6-/]OMG&>ӉK"ϼ56@#ᒖDJ$ՍDRiX;R8 \G_b;hנ@z5OS MOS,½j˲o]wIU-Sz~6~tK~I=nPn`r)?m ؖ_zpyR[ ERhA9qcDb8e@<<:G]a RZJh]g(˶HЈj FA 6%2U9+)j5< i9|r}cƒQ JRiqx{댽F4xʩ8ںHfL}]ZAnϳ^QPVVVxбVzm[5Z6\g [^ə!q+lYìʔESmϥ)\1-EilaH Z]^1< ,1_ MG,c=Jdeuf\qEδ`+:j¹nRUOIAcFXp-4D|hUR,(gl”m; Zk)J2k6w2ޞW:.=ɕERkIdI)#lnr bPc-a U_gS2ee!Or J9W.'|N˔Nb\s..r Ye8؉F~S$'P9d6q!֗ۆm =Vۦmly5Y~/+`i[;am/|pvn._ټyP `ibl)lm17Hܵ%NO1*eӠǧTpec.q^'Dªq@ ˁmU;uMU'(ƶ~Nz%Ԟ婰|k.( |5O|5av&Isl llՁ}+x+Yaؚ fQʎ)PY_iMjt66lFs%8@Z3o{MEQr,8m.)ϟ7*fg\R*j=g:Җ0]|)$5mf!?Ց' k}8Ra6 qr/΁c}[#*+Z[.m]K i j>`KyްK$-`ǹk׮L)B}=}s$8Nm@) v^zb}I[Ӻ]Z 5ޞ)l*Gյ-z.=I6fqS>xxtG)dL#(Uel5>`,*Yj?e ̢Z 1MM ld'.V,P SI#!NZϣ=ZF/٨ﶿvC\jB5Ea[ +_-jr0s8''tSy&omnG?p㑕s=llkT]` 3q`Yc10bJY)U+3-EuiZ%l9 ;D0?v޻fk ,kU<ֲz{]V#INHKC%F幓a -0s8 pK79em[b!1qewチS4 )ɀ@-eiS#b! Emi1*zVLC46Nq ip9gK[J";PPJYT#fUvF?w+_K'1WX:`k˗Bklm o=vsؿ9+\~WMLh)ss?xCMG8`%xvl6[lY]"09W<<pWT&kd ljU* NU g\ (I#hԑ zʚhrU˜:}Me+}'i]3,穬׍rb jF#9Ȏ50=l~G±;ֆE.--=')l8>6iZ[$cZ#wgkԬ`m_l8 G_LGBf:"A]hFGZe>{azfο~|@Rz쨭h5K`2R5/ӧ/>cIG0>=/\Ll~=Ea}BփLmʜ pP_ F-6e%0 oP>ƿFC7n|7k$+J$%Ȧh&;6~]*kbQR di. ef(QCg \z211i}֞A{klHqB\c J-cmE'$ryykMQْ_Jr)OK?;.ϝ ӯug y̓ _x`۶m7K%w.ERuMSbՆٶ>6Z6)mO3Chr:Lz 2t9uYs L/c[۷`0>6păJa)#ʖ)KU𬟻L|b2cFãe@S<6P(5|dngyX]LGf$jYI$1 g:)O<8|v=2n:Y?;7΍3CU>n`?0- <=0/g}.-K۸*3eջ~w7=}@1+i gg\ 33ajj:LMMɩ\Bkk+ʆooFK!c" B OO+Kkss-ϲF-u$uX=GmdY[opӧ i?:?Aum*ܶ.KQl[SچJs~>M\D{fɓoryĩ\c'7Ow sb%$@I=j4(q r[nՃ֛//,]:zzvLiݤ\֞S鱱'^C۶zqwoڴ6m 7t/7o+7t/~>iӦ_ضmͰbx44IiӬ˸`;|mGL,/O/WltZC$ݷklh{A\:wNJ۪z^>===ll9fs}jx .R'IO``ȁ%$~G*h3~g|N6RxM7K7t/=7w9VeX2n )Z1fH)əX5mCX6ly\l,YףqIQhPRRq!7{)(5lg};g#,q7b(EQHÿ_trORR43٪diԺ|-; sT0|g; W֤RȘfOAc)lF!΢q/9Ս;+pj?˲gku^&i+vf]k ~[.ۆ)Hz_,+5N,6J;nײ+w#iQ}rGGV뱲F7nsKUq,KQ6-Ko|TIu<;t dĔ6DBPLF(Y 2HJjFM?{ג#u\9@АA0!-pR+Pm@/B[i wxڄԴ(@P@ OU'̬{qsbE(js@ZZщu"vhe@g,N9]@(Ǭ^{ɞAu3tb]>UiJq 13\jv v*3"qUcik F4}' "m#➳7FUzY됒k8_jW.L\s>2Fs:~! իe^PUnTuAȪXc|ֈhk$k0uԩ#(tHtl7j1V;jf(k;|@k]LE-f8%\k@+bVÖaȒH*zV% O!10/Q6޿y ܍,\C=o:N׻IdcA@[%WMxOc\=iX^#['IFbCl ^ۚVɼ*5k2<Pqn]%|?J:qm?jc"&KDϦʻ@[ nq6J}D@ Jv?+g=.lvv?fD9dpEnIם/KyErٮ!/ܓJYsw1(uWL)5#8QQ 9hLTڋ9'"PtlM(^@1s?9g8駪ge[/gݻ^Z'e^ 1,܋ԻBx:804 DFt Vl|lTgvYg!O<.{nfT6EV)ũƢZGh$Cd U͗q`.!Z[cs??gHϪZHWA^ydɀ[%8+Eeiy32sQ8'–FfѶw~H>==w ޼y[Yȏ*D#)jxQSlqb:$cL8'jSJ *F*b9\m~)׽G",ڝ/;:)I JEC*}fD9ȣaѼt/р" xg[?Jh# %gL.AsNߺl-c!V马wϨwֿjDު쑬WsŨc\SRe^,,k]c6VVӖ5; ]uB9/u >XwGR1^+=`HμNj]/2fOC ]s{$PF"b WYkL`Q4W 2JkADϘUP>djY5&sR5W9oA+JFV5^g$|mǿ_F`[ĠF!U*j Eh3򑬎M]L ک8B~D"uq"$8Ƽ3T:ogGs(1兌,""N1̀;Q?4o߾ 0.2 :.~kn#{Hemk^L5)A"n, 2PjQjk"Kv#9J$FIuNpl$FN@mDJr ঀZn-TͲ2 #i,AX|oMTcv#vMh)2\;q1.jyElva=^/=t0Ђ , k&KectE4ص֌?62fs6;ff:܍bu[y{"[hoSs GG?GϲsNFcT :Y)͇ ?+t#mgM@E!~'=5;jU@Z%{Py.ɻv{; yYfQ^}8zFlD9@)L4O+LaYt ޲Ԡ*BJ W^]p2|ϝaDˀZ6LEG'ToMWQ2H(EPNbLd@mh1vD#hd骍ՠP,9=fkpsX3/ u+H̻WsΏO)2:R3Se#ZNJCy2]oqmW 1YDuent-OEyX ,![>sIU2#x"qeYm;j_ʹA)HUbd-xN b]h+K]^9^,DmYctfC:ɉdflN\t6si<{<78غQI/F(v**PE&YUJ"aelZ5ȢtJ\^h?sX YY)0clL̙l[X1&yH;bY?UC&l+9K'jU=,lWUQ8 1`d9"J7{'kT;jC(RW9e Pwv-KP׬xWs̓E8yTMznT U%pRUj8{jU"MVe&.@V5z Hd΂j{NWź,Y]0w"3Aw}j$#8BS`g>H։bt{婽t Uk& <%Aa'yPl{s]ŮmTZ_('rXFM1.QUl; yXQAJNJJ_߭EsSHwrNm7%ѭ"^:-8>(]ZQ{*X;E"1 RO5hKEPnh{HgqS : ljܮ$QǎrrF*JPZ)7@HQWdz:1*U w :ϫOqw{^!RJ+ ĉ9F˚PW+8M;J Yasj檽X4\n:3k@\lic鑪5@|; >Z Ji5"{l5բt َ\xՎA8ʰ^0ce<ʳTi0YjKuga'(#BuT6Wjl]XMpR@]UIwtSE+"JPYVTj\ceg3-n$_6Uix;f"1>K [Dv22Rs:뿳G怷,b($6fyFFFFpRFk2nt'#PFYItߑπ+J33X`u60/C+;6vz1gudd6;|?622221>;?2;jrh 4)zdH(juS uv_3@"\_|N:C2um##mddd䂀)J,)^:E@Sv10tn#ged>k\ yCϟ02yddpww(7c4G39mdddx~+ #ljK)`vwN<Y"vawTϊxtߜy5g)Geڬ\KVO8">cT\ʻXUSJқaEt wjR5A2{ l*8,##/ Uwﮀ>tSO0;a=c 7g$n,sDJHUhv\W%9P@HBua+ JEIA]edNJwTRy|FFFFR9 ʉz6dP.Q(SZȡSEFPRc*QM6*hcs99{FF^TNJ[[9:]2mddd Sqi߫dCcV͸Iϙ:vTjݯ8j=fds0^lޯi`yR+NKTAQ@ƒݑm8@Jt'*>CUՆڙ"F6K?Dˎͼd/F۫Ϻ űMTmdMLYw:-D:p" 14T8&qRcJլXʈX)pW <[at_F ^:Q*(ǟ;P6222RȀERs;=gű9iyG)L4~ Uw3Cףz1R//Yج>sJ0Fy=O&fv=ЍԹ-^n `)(d(Z0ݡAFI669eN:cx_KHj3( ddsK|wHwf'vHX3 ʑgQ׻Jɹi|F: -wAR@|9uoG0kf::L5222rI=YqEs'6222rC)a*Fx4u=nht|xʜwz9tNJZݩc@ydddR7}+*N2"y1u6;gVZT'3pԷ1fX͑C?22y9 m~և>jr4jf4Rg $V] j[A$722m^FFFF^zڤeM̎A "@  ̞S֤isCׯYŹ0tddۼ^ĹvIENDB`admin/assets/img/social-wall-graphic2.png000064400000034727150515074560014351 0ustar00PNG  IHDRPWPLTE ߢݢ쬥榦̕쪪樢԰}ﭭﭭ멩ø처ۦ쪪訨駧꼧ﭭ!!͹ѾìɴªŮDz ݩ2c8:&(q==J8mIưhdⅾ物-9QrX)UuraHi6Y[SvD~Uu؁cu}MM//F镵e욭yQhtRNSCc%ౡ3rSSTE5&t5ssFDdd%T5Ѳ%ಢd#ЃTs4%eDDc$EscСDdcT6Ï2b}hEs/t]0dbqc w%~0+)3% \xvM0]u鏿$?eWSs_ \ȃ\jLw%oh@|O8a%ĥрn4A0/4#o1&R7рVT=Z 2>af..Z"}CG_پuܚg!5E0cri꿞$/]6{Ӏ~_DXJ1E|v> TGA d0}Gjp>[?87+!XYRuLu6A8_; x7_"n dV _ofoz'l]H}9G/$<5UA܈ZҀ3˴ ~OHhi52~6r⡼߾׍*B:/f;俵475 =[|ASO;a@#r]o42gX)a.WxpT yҀ(XE~м[Q{BvA@*r/&_S$* |HB 5O>̛Y}$mB;dcA@ВY z +x!Ӓ0h@%$ N3VԺx @ y5V 04 g;ڻNsw/9ݵOkgn\lGpmLp%^o?m2HwQZz#G)0W" W la.nKã^CV~E.k|=Xf? \i 'w]֬/%ɼ7YB$θt6<؍@-:*`7Ap`qЀ>z}kQL!3^"~_\h4[JN`  ЀwWvO5dpg $ D+bx9D)bTAwdYQIu@v4!.`0gH2~H&`aYEpӯЀ${Lj* 쮒 0S|]p{z@KK£r2=VbT3{$Sq+@w,W zMcE=uaBoSJ~G1+d^[臬"I8O_ 1aIEL J (y>;oA-}ȼ`G"& \pb-0å9.=1 րTrNNga"])ؠ6AX> qg~ .IS_30LA@`Xb> (bf۷WBVJapW4Il aYC<ޝ0T/E!یcdޞa]]N^ KwP܁CN1~D1"*Mr/F}l0k"{"G`|7B~Wz . ou/p01*MA# g&&0-ww| FkL"*pݭ&! Hߡ5F]+5w+:寀NY*y'?iT 38^_fߎgG>-FO:»'xl:s% a!lEpRܟ4H!!p4`:\[ }DSGwfbb4\?䔜%c?5h_3Ň'>Eu8Ôo*1qNkP4 ?M@_hAsY\ p@t@`%3yח3;Gx7t2 1$ѓB3JthgwP34h9M46(>H4y 5[|wD;` w.}EiWE x[@00ʁ :BAh?slj/VF3͛??y՝3ɟ02Xiq]Ԁ`:6;M]?gh!la#cS Y/U704ARX61H}0cL1>uT$A8FVfEC~ٱt  €f^n0|620.ݫfd[E s7{a%uԘ.3'TW=Ťq#n%Z7u7FџٱSL 1F@kא91UQRtߧ@~)4 LGJ^5Ub|;d +*j}/uv]HS佻y-*ݑ3>;.{7GuOX1R2DOS-u7#o-Ub4su8!ȯdώUQUP|Oezw0<Y>UI6GNm$H~X]JWЮz/6s0>e[\+ lI@:jO n0*BR2p3|2ߣ&1q:N"o"00.Ez዇ݺؗGLy~:v< O1O4Ϯ? wn]zPECG; K"o37]i}ko_E%ew ݕX6Sƾt=mmľt[3&%mMcaA-DdlDd cN}0 p婺u{:N?zH[U[S g{U&мB%˷@ 7 W?o$yӤX6&.s2(uO#nS̩^i_O[hlkCf} A?G'A+005Ifd:PDō[`40g{jg PcIx>50~v:u2 X!j6hO{-%j\ӑEY79R^4Vϥe@4UmSw520ZFGF ҼqEGV^S[/57>I>4 qG [D~kYMgM>2-`.᩻K2t퓓o->4ִ\ǶEctmo<@ ?Vx(% 6N4J~N/]ƌZ }|S¿~yO\W ; =@]F}c}*R?7nۀ2}W4Z4ZȾw/{C:*ۼZ7_u @%<Cn13033]2@^%~\cL1)f`b2\}'Vx>E002ڹc2\͋Ge`2`cs')|D_Z\gbg4OʰGuo Dkc*Þx]OM[\ˀE/OPi^iwA̩cڭU(]^AWJu7+i[# ѻG~ 2|q.nst?o(7NGv XX(5RG9k <Ė}uʿ_2ͫ>Qk8ʀfOoTwہΎrw̶C.\"Vwp ~=m!+HOaΩv@-N{X ʀ _ QR,ڝ zZˀpw7私1cѠ@f,Bg^EPӣ[s YGS\ %{d0 @xچA3dĠvuDڤ %gPBjO@x:ȎP$/J%5W'U^?_x4;"FUad/FhtH !}Wث&tuWy.9rs(eJ ?߻xz4RݹWMF# oB.2\-ڴ!BӘ4o>_nV1] !tEnD<|Uܫ.ꮈΰQꛓ1-]e@X,kj>WM-] ;ZfI2<6]Vث.4˝n8: < rAn+g戜;WM-ҾȎ|w+B[@ * A+_sQ9Gp۫407Y(2M?,է8g(]>P̫ٜSon@r@)w^9 ~BmQQzм>f@B02eOs Ͳ‚@E02 @UJ|CݥjN#F{o,7{'GA>JGvjBUwߔߍ"DwX$~.׆1ʀӾy~h w[ݕ?憄 ܾ@0*A(e~-Pw)Sw3!Me ,: `Ŕa?.qPJ>]@F(|d-|ELe{p. j@ žE] 3#bFߣ1ʀj]|PwJe 0"(>vB' WcPU O%[Q@0OBiM ~ie.3u@^̐c !fP.s>N~ҚYuεhgш_E+8Ltƶi& tpA%ˊzՄfaS內_NaΙ 週\9(0mA 4qh'+PENH;\2-NئB&}ڽlL`&ϰk(L>KIE2lA,J=KA~OQ1!ٛx8?aמI( @\Ӏ(W0c/yL )^$ͩ7Zg+, sSU(X i>~"1}2(6t` 0*~VbsX]~Pʀ"YHB0<衄JBsƄ ,\[ј U cD&`k"sgWp} nPU25a)Fhpod+\ m u 7 Nڟ .JB;%!}k\،^5/4XSEBe(^( ;9\|3'sD(P†( к@ 'XaX{Yp͊Xˋ-+/,BFϨmo<(Kk'%_ʸ:&+/@ V%Gӝ*\oLH-F tNFp(P^DHuK)&P?C0l9p2aMD/0١d>HeT -rPtK>=-8g@$٠C0#W:lJ8/>gea tCnҦ,#כ"c{$)&'4:(Hz'zƵW}ĝCҤ {vo?z#oE?ceR4:@@buUK@F@ IoQ" ik޳ (exg_^ry,f,s"* BW'>\Tg@?k7&Ik*?m*`~G(S˰a㺜pcc%e+ ^}ŵeG7_p[~Mlܓ*-6 A*Tl'PYu_FkG]䘣ALozX:͉Qnu׵bf`;La"GA&uƬ# C&~}JXSk걭,Q~Ԧ덳,DM *k!uߩ½_l\D@7ђ0%] WU7t-lюW  ~eW. ] i"11¯];ľ %V1JA(D.#Pw+/L^+swm޼]U"PLAQSLCW6KAsJ hOq#!poc2Q}Pڃ AWWWwA1ex2'zxD&B>aԊ[2\AOݐP^QT"r+oQ9=m02%؇}xմ1Ve!CJ_4{(Q:`N1 u_LҼum}` iТj1a2\b/\Jݐ17%Z7#"?D&A6WTa0P ?h<:+ûIwz}ChL! tm:A AF 02 u׶,׏;pژdů, ٙޗn]03% uW^F'n&FP9A&?}8=>ulWv/p7^k;:q:W GWe/ٔalмܰhfR=?p׶≤@vEmX %l!f E/ ?}=:psߝb DZn90Խ@sqШ+,d<86'W 3~d˜!R'&0]:Jj>5P :QQptl$Wܪ-hՏ7ĭ%JNuwA~&cXΰlmk ɑ^D"{2/uapy&y,"\K )_<&vwsB7UbҮI20-WD]Cʹ̑?PF-zқ#m׺?K^AwE;A(YҼOKI@f +;>FA02x~w?x,iff/ca!bBB+aPg\anGQo}b9~#4M(`ngV%xސ)msw IƀQo]}&} ysw@XX oK™~<%vǻd?-Pr#ԆS>9K_"*#, >GF{Pzu  Ci^a6T^FR˿E}.fgdZRX\Q-Ӽ/Y~Y-FBVaH?G>k]([w4ߣEޣ>07/Pa|1,^r7d1#%.`,J4^%vwK)>XP|p3* i^>'\>X O|x{jwS/w=Or戾Σ>NU*]S/K\^#E'Q:AkjשH޾](l*M{TJɪ>:~'oJwok> *S^>zj*_ Z[XbavJEϕR'G$迴*e~: MmM>O+{eSdWJ|w7>}f[J\'OOvK~ۏ>tB>Cm݅\u7;kL`D84ON1GexAW2}(^E+Vw{,_G<+?hJ)PȄ4kF@;[^;0FpѿX+[րo@F9_W/Dx 8<,|(2SmhȀ)wc.n>؉K] 8MXj2.r=a71Q}po(6էNWlU0CaS-(ҹ_'"~vp{Gr80z[%a\wѝ!'q"d3΂0(o?7DI"K% (g *Y}1X\/ѦMa 4n"K O6/=HV "%<on^{|ݚ[Z j[7ڝ?9 +U.Jh-}Tr{ 'p"bA2aMV̠wK6V; gxXl)Yg8vwB%\J˯!{@J0%7_3NJ. wm $ ֱAٲΰvwMqRa߮P! Y3lJ4B|~6%Ŗx^qڑߝ,O 3V%R77J[[̟Sxa< ig.Kf:Fa#a!(H:yG+Ƽ'u&^3K1%ÊVMS7LnANУA熨 s˿,ggwK(W^,w |!- @ 0o9J:ù>]!˔j"CDh8b ω-Y#7ɼ81[#0:3c`H/cxI]+F=cwKïs!b],pUV}fWj#R/8 x|,49[2~gcV`\nͦBa=Bn>0BG.r gom}-6k/N Ed/rt~ywUr%vy~w3<y=J?KgX +ƨ 0pħԧwne8]O0v\;Ax043nO9/pw!䆙u84 `)qKXO)A!Z}Dz-ok:xRUߋd;G,4/FsK{kU@"7 ߃Ro[A7D֠0 -񦻫e7 ouɫIENDB`admin/assets/img/oembeds-image-2@2x.png000064400000217312150515074560013645 0ustar00PNG  IHDRt@ pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx}\u%G8, #XD#c 1yHOx3)<p4+&L1F&}xI[oAK-[~i;(KdnwDRn~I?]ܵ{[Uk]]u=gZ頻=hhhhhhhhhhhhhpЖЍ^{ ?^\}gCWmYcǎ׳Y<[]3oΙkw̄uF]9cGGTѳ.k%he:h%N}w`Hܴ~ ڍѻnFQZ~u[y)/>MRJtۙG+3(Y["Wf֍PR;EuVJobwD7 -"s,ulͦz)>}&ڮu\#^G`gtAMU ^m)Ug]dȨ-.N3d N3+ZAj7ҕT'/h7K{+ͨm\vUқ68F;gi7[{}&sc1k߳oMNRkײm)Vv"7wAGG:?w)0} JWob&W꽋Ttʈ6eVA$ZߣUb\hۣ5b{.vu|ZMu#Vanckӻ u meϻGo p _uk]QrߙoMN2W*KLd3wAGGt= Ԓ.ҔAez?[vvuر.q.o`?Nm?>cǎ}_N\?Gc;ooI狺 ???ŸaAw>tBvku[?:11YMO@CCCC[mdz?j4pԏ^sС^./h'411u_ IQ[-gR`\hhhh+s >|R-ibǏ|61GRLa_eQ8qrXPzMOD2>~䩹z*%}CrXCCCCC>Qo2 mzDYx%ޑ}#1ɌȥCCCC{ \)CCCCC;Q׵d `:44444tҴd KKw΢3$Tg8CLVI"]䫮thhhhh ny@|Ŧƶ%ϦK\_:Mђդ>V\--OiWCWT_? oοmd@Y)hh;yc7AC]#߼܋]gOecn3Z%j`[G~UUnE@Ǚ8 yr:-CC[^@7=} ~wmW X^5˥N]^Uʥg])] miݣ3kw8J4k/~ kFc5݋wmX)ݼ8c^/:(yWsb? y)}]CY) HDCQnxG7";r-iCC[~Qn\t](ҫ(r,RB Rtٷ &≤CC@ ubE: =ܾꩽnQCWx @n9r,v輔U⸜A;cR\Q=Y7VǴ  mi)PQ'!-\RЭ tUU> Zs,UJ[7\VС-K~ŷ^XUOu@rC>X ㈵1:Ϡ#H  myEQƎkQBC{Wα#Z&:lN5]KmeS.3 *hhUݠK2%T]G $ò'Le @nz}nV#\Uϵ<-i$yrqyKKСu'〣R^ܭv{=Z2,)6mk/~;6Ɍ@M2] fS _繫-@C[^@{P~e7uHlpnhyWgOm%P=Duxj|Kyn߲D ]Բ}JQC(ݲSN֍u~|K֏V{vez\I|~)4AjкCEngzIk֏V9/ j(bbU%?@)bW_CC[f@waפ26v+]R. +ݲhCC[~@{t/~c,5ayJYc,:jк!͔XjzEС-ا,jв-X"U5@N<gdѡ. [?ruj(m:44^mAmv2ڲ~RRK䁁U`zQ}IVnt9IСj{菆j'8w:kqR̰x}QCg!XtG' Y eX @tH PGG'N2:44444N;dMl ЬK YFK{cq eWYСq]%TСIsRVW(ZڥY duAf,CCCCCˈd :Rq+m 2(`и( ;-9S@ix$*#K@j'IÇ JS$CCCCC:E*}]C',o&Mhhhhh kthhhhhQe6.д^q>t::4444: $y\ MRsA𡳐k *hhhhh.#NСE)c` 40'%)r||;S9j/xM/8q mwI5>>Ui@$VqrcW_Յ *@̘nt}˴co;?D sTGm :rp?㫪C :t#G\咳stumQ3DQn/x̜fY3(ë!}k,ގmR.aLTC #GWW?WG7cq. HD D贔KJVtOǷjrsNf,@ Б0JF#G!]Ke!A\ٗRRC%@ J*m h% @ek8v,ZEtTKjHD -ЌiQ @ YCU?XDٱc5t @k/L:;rxX\ZWm5H!\"3tr﨡C cc}Cy:xN.:@x"!:/R#V%W, j\"3tVe.XD*]C tЬ@Jt@W*bS.%%)})t.X<:6hb+ ikyYtR.iP@ t@'U.=uKK2[GW?g9\"tQ!;- @@ HŲZecYߌy:@DNC :5teƃ @ 8(ٱ5t)"ΕZU $89 @@ X\3(DQ贱D[$TWmwT\"t}r cq˦\rrJ.Ȱu=AF5!Bi`+^RZ K@H@WtYx7@A@ $Ә:+mNӌ"2)U?i.*dG%@ $(B !k[8)"T.5RK: B(]F B @EN,^i`!ekt@G)Z~$R ~a4 C@ *K' 䡆@ j cqM3b` @ q?!"r)d/){Q9dC $H 4GC :Jcrg,n:tjU֍7C :Yc^okc,P@@ ,>([.SCa ϬQv @@  41(}@ d ]IJj$ⅱ8@ J5vh@ x Uf1stU/3tu|>t(tyV8r@ yReeз*gC%bvvfgp2.t4{,d!҃13;WEQ@e5tF_f zjSc[5>>".pm /U۪gcOV۪Mmծ}Vuσ]O+Puσ 7ގs# m0n4=ޕnC_/?Z9[>vk>y~}}զƶꩽϡ :wuc&b_: k+X܊wse__OU<]}텗svz#gVݺ/< @@$@7::zMNFqonNb{jؽgo엻sԕAe󀜬R-c}W@|A dgfO&d4& KTK{Fcu?1t խ;> ptGG|1tMVT ]ys˯Ru=6~텗]=Qݼ&McO6Y]z`wggyyխ;v=9YyU;8}>sO} _#=Y}fM}~||t\ȉjCO47&ߐ~obBߐO>{nq_6?O~kkt^jfvڽgkW k[&ff-n /V>x peQ;D<ٖҹs'o@cw.y~޳wyoՃGl[~xytyc*ܱϵ{0Ε+ۧyJx7T*#yksoE:ƀ0{̻t3' ~s~}]tWBL=4ljl[0?>>94_.n?b /rk =cE=_Z?st󶻛l7kny''z>Z[^p>O3⺺;r v9B%||εyu7p 3mGxyy~du!VQ$3g=uʥ*OJSN9n%m{U}1od\Q[Wc7oK@Ee>)Ds*q+MqK@1.Fn9.oB~y~IBמ|0ۧm끎_*Otlڹ#@yU7ֿ&^G:^[3ݺ&j||9I]`V/咮Uky /V7Q xG˄K+T۲R޴t8Ѥ/=Yy+ŏl{DˏW{Gn[3-w5pÍwT4s/:{|H+<^w|oHΩwf @qI3.it%꭪v+i"(vIo\4NKmft{ꍯ~N~Ă} &|pbCOG޽DR@g$/>ے]3Uઁ^y{0}-'IEΛa-~$ERIvi)bqb1t4pXY/܂{ӭ;v[$A + :g[:>>U ƽSTWkyh߿n$ѽRzѭ(KY@QZC TZDQn6RlJ&!w4Yr LVX%S700}qeCOhdAݝ|V:\]U]I‹Mh E`wYG{z}3kfh wݮsE`#=Y=5MehyV 2⼞Sk@gZ-v Yi{3<+羽\cOi>iB-FtIvлyi= ~7 %/3+LԀ1?G^[z {ެk)t[Z@H5hUUŚbI@z.,ty5t#ySe%bt.3)ZJetu yV xg*1sa)eƶ:Yļq{*XNImؓ 7\Er hDD?79Ω,rh\wV o2spK6) ˿Qmfg!!' =oZ;:D, ʕQdRZJK r1k] >MDl[$i @{C;Os-vnWT Rۈ &J;:rPF2}w#@9H|.vBۑ snܾT73{n~dz_ޯoydYv =EN:--, $:*3_ײݦ廂G =OS@2, tN:nCifvy _8ܺ8HݚE\_ߟ}]Lvwq%'F߿XظgEK~4U皩{-xytug < t^ed.._2tҪ@\?nN5@"vy3h,.j}/PIv&(Ak*MҵQe+a倈y _{%3wz>;2'oB,7: }Vg~BU/9XbN:[:@788vǎLNN6"C ޸q~bG6Jh|{V//ĸbi tN:MŻ7o&4ic,RǧTME3rfvNѵ-jog:< tkhicEQk1?^;xhI$7n ^h>W=0uˣ=O7S0z) Rʝ64yˣa}^_E }#vJ~;:WI}fvv3c*f?SzStk/ǙM6< Q %?P}wFѵ>tnS{sӼ9~+a1t޵'{G fٽgoݱEC952tcJA])^pw[ Rء՟9+j@4غ~zƏre}DXݭ RFhHX-mCz\޳WĄAyqq`Wg,u+IڲDQݪ"jܼn-k4Vk@[@t8^vjfvɀi·gXـ.,Z_{>[z@G$uT?)qe|v8 N[Q*bev._^1VJZSJm3@˲]{:.\JWwK=@g:w ;kX588vhhhZbN~O:)Il 4k0E@@  $c1X{i瀎T+ VIc\@ 4 D)QY:͇NғP@@  ,@Y mܸqƍRz%8688X,bw]&RdH &# @ 2i{ms: ԬUi\4y<=@ӄcH){. v25h\nܸqk:OiџZzK\QB @@  2bܬkX\q:I(z{ћNF>tV݊b'bW_{EB@$ $e7|qƍkyd8sGk! hC ^w_Dt!˰s5s}r遻)bUh:Xg1t\t@ WzeR-3v}i,9%@^V INKä3*mt0%XIW CYC:{]\zNS$ 9bFFFX(Xǚ@ 0Ps3 wpZ^}ޥr+~nhhhk1)_#|w_9qҕ2s}#I|L:w]Yk q9JCCCwq CU@)T.ƕt\Q?,cH0/gU::w@]]*cK@ŋ{\rhh x%g:#Gtԩ飯ݟ/V/^\9:qv\ Gɤ[uʥҁC,vOU۪]=bc?\mjlfg^~5/VzG{ svvzg_}jwxyz'pv//: Uh.9 z\/+GȚ7n\;88vrrrQj2Cx}զƶ굃W1ht /V< ƖGlu=Vp̗߽<|]k^Uy||ڽgou;N|:xl)9+ s\dED@β-jRz}]3{ xGu=.w`frz|=O-^ךw|};۸y$jvvy35w!g4obĈSMXr?:bג `9z'O3nX+3lkˣ={Uc{w[[>i/nq_ڱwcˮO>,nxwl7֕ƕt^E K+"@:DǞ2Ou(XxjSc[cO  Y. VzOyjs E-65Uˣj__>oWSQ}qBkr8;p^xe,&:r tdV65Ӕa4o 3nq_usvAn9~ܼˣ>ҶgngSmKm?aX繗ތJ,=Jɸi@H~_ۚ\ ^GtQM1t%_ "V^`a;+?i?UR%s t <9Yed} 8rR0\Uy1r||z' {4kJO>Sճ__uσխ;k>Ƿu󶻛YuPT />véUcyCu} \u>Df9o[O}>U=g[gl"Y]|y~_u=rZ!ͷ|mW>x{w Upj3s={Sj#=>c}W w3?Z'omo/~|vps{=z]=^ xGY pq[L<@7pXs t ( tVR.* 왊sncǧ?ti ~S;&ٻzYD7cbVncvU)S^x󺤻y.gk>߼ Emw,>>dI>߼ {>Qݼw|ͷܽE[Nc^qڞWE~;tN;-׫-8;D⛶zw-w ,@Ghm?prVXYs t 2F{cqyܧ}V6&Do/=Sv`XDZm]:vɔv@HuQ7ޱ|k`I皟#-o}_}V%zrI#y~. j4NcI gK-) Pi& +hP֘^d<7/Ͳ)E:n[ P4L^b訆Nh3{MTetse h2A`j~qeNWE-լq0v%:v P8P Ŷ&XCۑ=N]@o\΅…C!xݧB:.e-ȺfId=tPyb(V nf.@|KXmb=3{' 0(eP[M&1fg5T|X슕aVm̞nJE@T.bH<;;WO-D-r;8tVkVQ*wTzzRs_nHO )) /:B#4H $fX{$H*$x#%4׹m"JK-)l\o{Q#>8Wy'ĸ =[m?#Wn[O}O4_#!&Ï:=%F=36tsgO1t^mo-\uꩽϙqOc~@'$d؊tL-m hr1CS:ɦABJdsk,x%Zrr9uTCS.-ph;vi:Mkme]B߫5 N~/f) ؝PoЎy /6xw~&t<`; Q/=VR: Z0FxG{k.6h)1gzˤ[J'Yձ- *xjsʹ1Xj ]VYo7Y7g~S[KgIt+ϕ::Oy9>~eܬ-DT3EoG'0.~MDE΢~(hܕzu/ ʼ-v,Q>jq7%Q9ܴ=:(br?"%ȶ3qD yIwmK륎jѠ^tYn(U;jPRF>'}Ia戥ӌb_MWƕ X@Gk+\&:`J֎7)\;WUּܲ 7֖k]ۂYOXPBjQzɒ0ΕXTrQmJ6QO&|BkN:Od||ڽZ&§ƔDǮyew>@j|KEW4!=OQZ=O%5ֵ}%ISE;%I\Rpz y"sfi{e3l̈IKξQuMNN⠏]Fi+rUIswo=+t޸r||ڽgoq&:]Y@O dte6_=b{^;%xas;ڢͷmdG}+ܙ 9"53Oj9l=HFo|le1t4Qۛ7+21pon Фd;hRN/}__ݼͨ8 $AB+\C c'\E Tkh H鶪՞ˣP Íx t^>yMRa;8}ډ|gyU]c 9 n9*]&m3 ψp#$@GlW$9@h\\FJ$~ht˸Wؒ htRcfvy7U&?jo\yB+4PW~+Y@G^li[7a?O\3{V sSc*عn ;Z;stgfZƸ W?t?j (KѮgHHuu/tK5CYʺn- hR4a K)@Y0{묢׶- cnz%)>,xڬ=(ݖ\<#׶%3DedɽgלfΉw-0Gm=B/ d1N(JPh2ˢ@&'Ǿ@B'4uy2(%x1kk#N5@73;לj]@GGniYM-ݻyP+%)>mFojXU=:_|\úˤF)־g-/=:~eHqs teU.K\2tSn-\{^xffO7Yk>cISNI텗{nYv9(0|yt^w6h[E"'RtxZy$*w{']=Q޳7JzjCO=O} C3>fj{S:MCx듏ǖc^.<ǾtCu;CXևEuՏ;o;.#XRRCj.-(Qj/lٲe #V@F/###k(xz:D7O+'RzgP*nAduLt JT.K\_2tgXQxs ~nqkXށWcr<'˼nmWj}i||37<\ETCG'Yj2kW85(U@o.RJzUTC'Qn8:T1??_\l'ʨBfJ?eثLMg@S PnٲeƍnٲeE׉㬝TԀH-@ V;Rg<ˈVYY_:ig?`DF `R*罔E iL> X2/Ȉ:ƭ 8zFc5ˤ[jb+FRр\E@@ EDɀ3> E5iqIF-Sp \NNNr&''WqKvT[S.O84|!D:בM2Wʥd#P@t;KPDNXKѤՐY@Jdw ?O)T?GX#֎ڍ!ۂw H-l!DINYQ*8x"DQDH2gmy"^`&=ԫӾWۿ=Vc(86;w\?88騆nppp6]0#@@  T˾f2us::: `NԕZD ([zJ $DSLmf>ɂ[LiZ(7 A@PǦ@t*]zY+; `O=k^ڸ CWZYA(###kvܹ[>nٲeΝ;[y###km޼y4=} 9pB #Mm4㝧Ez:>3 my!.нԲ>tXN^5`GsO2N?"RO$b9b膇בuΝ;S۷o/<7o^O*;$.'vo F׍f$,C{ta2ut8D?: y6QT)xjl Enݼy-[۾}{I풀ZpƵ;w\x쭗O8cR&5Sжwr]:ZC ELe"EQ"VJC X$}ӞtmC{1rLǒ5#@G`mppp͛?rG=s8tEE9\j̝,fXH3S x.QUon:gV<@ E5tҺ@#,1T`r@ y$Dݚkۋ&ՙd,H+a4D*oy<۷ooѸv˖-ƵHv}m-kdF@U%\hi>m#@ Jl 4rX@&޲ND?> q1=H/6A}|]&۾}{wܹ@N K(.\P?~wrc;QÌ~(} #+`O!nt%˔(;{ PD 2VrbMa* "%8Pj$Khh4%/n%Guw$2??_]pW>걏ʤziY`g]V*fC  / H=toֲ)W@]"'r%rҜӈD;v"7{[3=^/nݺ}H, ܹsm ;22fddd?|>Q?WŋMpGǠ1[$RumG{ox>@ 貚׷ FErgY@@*^BY>I~w4ΨVf4H^gK@@DoaÆn6J|^Goذ͛7߰au[#<8},,1+,3)ɲmNt=@ 2J[Q▬'>YC  f=4 ^'[@t@K$vɈʥ&/5Q~"QC@ z YbDO#ƿ/48(FiZ|;1O,|uۯs~coWu]w]xWR]ll^|9lwyɪ$2i4,p@ e tPC@ Y">p0ؚR3 "F f5#u jÚΉM^?x!RfVvYWC@t3yY\ k2nCȜ:Y!%A$|"e%url˽8[G)֝;w.4+ݼ3bwkMtzw@@ e|x]rL3'*Z,,M8Ә:@ݹs窟j5vU9 I`'lƛN2M=/q^*f$@  TK~NZx:MMF fPQ3gMеIs$bIH!-9Y'ٳg*\/mm~f=9hrfOp:u|aK@ 9GG\?9 AJôc9+YOϊ:8v("aNg< rIpWba@@ %D_@ZT {ki"!;w:96W`ccՅ 3gδ`S xtA{ c[뗞pDe-K[:4Z2#*@d_#,Ld@N(?xO>t"J"n}fP2=|,/.#|CUJP7??_9s:sLuܹ̙3Kjy+_~;j[J`9vՙGպ`JQk5vEuLZkͻfy:BY#ȇ۪e26RSZ@0Xە2Lڙ79͊_x)^m@^#Al>lٳg2b"F-ka/]n,.tQg..]/5tZD@W'D\Df'Ʉ2ٺ8HE?Gr^;sLueaKU/50,=,w j%\-&Yzb@sʊ`j%T.De6y&dS0 kY$3@{Y 9YKku:s̲s舥;}tS,Fqq @]ŀ/ƌ8PY}# CkUߦ\j #@mx)e'Q:fF*>Y<]v^ڞ;VJVv@wh۶jvvŧ-)<+ajZ6cy">!6}#Dd,.IfnEX0]55!i5fM3@DzoiĽĚ{qp #-O:+ƿeF@GtgϞfgӧO7ٳg9.6cpr_ȯAiE]^ @ZNG t$AE0Y^s˾LNDA@:kRhyyU]֫C YHku_@g/}Y?Gt.\biZB6|7a&R yJ!?ri]jY}rYX &%?9X&vY: z,HO4)! S733S^:Ǜl\9M풧YjqO-AOJJ@Iq+г)XZ!̕0h?eru?mB?1+3̝d4 FKD,ӧ~70:ˁ%1t@w]x/:cϦVYX)%@q`{^s+Xar@ "@2Z~k.mbfrЄ5!cQ 4$,?GٳWeL_?VML 8[A,K Efu֎ǜ|VQu?XCQt[Cg\ZsCG'@d\Iܬ25F!SCM"Pii4h@DQ8C7;;WM}{t0X #N p~/ yIUOWXzgbe:eLƽ2"::trgD5&n4QHظԽ'Y#o3tB =FF2d]@iI@Yxga)Fb<ٺڏ9߼EvtV&~ϭcq e 5!k"+ϤrE~VY6tkRhdbo$3ǁ=>|h9s:|5;;r;җJWٕƁ pK $㿝';t\VgXl1?X.uxV(J%stBZYpul Vβ.i}O$3usMԩS|.fff&#Gt q Z\+:+ 7]-GG +qZ!+‡*R-VڤNLoM#͚LpIdUgRKNJsv ^5;;l`)͔3gδq3pl]3R]aKJM߀Nk\ĆowP'r!rY[{_Ue Q,Q*4NkD_23gLݩS jfff.O2VWSju*,3׬ϥb:ORff= q R˦Z@d,D倥票yYk-?qR+?ŗ6R&[^fffWL|睟^l%<;E}AI@R4 낺:^8G &p-3Ӟ/5I dzo)+gs#q@p+l@ 'GFN|+]ma|sY:@.˂Y`ISfte'عE !:`N+()mGHhis3E&&PΟ?63Sɓno?ywUAX=0浉ΝkCH,AϺ H-tx}c-,V@ VeF{@g8'&dЋO1Rꎬj`46 d%z:J$h'O11Ts5}9Vel dz;$(֏F鑝.+4A>uٚ:\"qM{O'T,5yd yY)q@J`O\@8w\u…4@nY@jffzm쮻.OR.9Ehdk)zl( eg2_@h4V[`[r\Q%O#0ĉɓwIK%<%㪗VfI#: =:l|Kt.Z\)z݇J8 2jtuX`WWc tV,/:f!JWQfԩS͆::~R-IMaJ ̙3 jxj،|ii}3k 1z3KtuY:bT.5ԁC *9ˀBLشIjTo3y jth$p:JǜU"*333|rـ>گG[عӧO7 (s@M ZK-5Pv}\KCwΰYKEFQƒƯqֳvg9p˼@@t/,QҴ˪DQejt^׶M}*eiYre-%"S4RRiϟoD8sLNt'OZl_zl 8+m x%]<ΕL-NfkNZxFu,3@/OE,)hHǾ<,Cg 4?.O gꨎ9.B)SSSֱ-uxf)A!@GF@Y4LilG̱@x^@bb>=\J@YR.ei$:@LJE %v"5ˬhn<5W 'U%kt|6Ir@ ) 255Urujbb (R/ GRX5fNJbY3Y2P\^>2V'g@+@}ԃ3{: :0tDh2Ye>kM2~r(3eY\\ [LCiR_Eζ\Bn_@d߁|rlja爭P@ J*gΜi$~} ZN2tZJq/ydxMf{=.r1tYOR.5B<:nUelӮR-R%tls.'ZO,f-H WTHVsUKJ䊞rįn9HNr˾"䤚j kF%cQZǺqE!;]n=])8Jf)2[. }&Wx XMX“$iLTP$0At\NX:bx%5f8kGD5/-k&M T$f+, x="?dz:{Y^'iHER pmwG@~f}-@yh*\e 5: 2LZ)#bMJ|xσ.FUWgHY5talF`[::&% Б#'NXsj__TC۶UG>&s~|nJVW`G7iʣ<ݒCf4Fbyt:*8b:)ٌ[N2t.ӊ e!2"'Y04N1M%|Gf+AeG1p{ˮ3D@ H ;qdS$ԩl1 $AtO>tC۶UGキOV'ƚ !gHDQ%r@GrPYg$Ӏ&,]I].øY $=p;Q,MDC@\5A$whZ5or2)S0=,m˿OcLeiwJc؝={Кu拞~ts [Hrs@'GzqWk;~cYwpՑOV_zux D~qO r9z pL@7 - h Y bX?b-^e͑r@txC%Xʖ}riqƹ(ћ.|e5*4eW޳iafD5Jk@s^ʝӠK^Y #&(>6:OG 9sM@|nܸQ??kox7n^|^;xeq&Ku6SwԩFW@pA,r1*ϕ^ԚF%#" Xz@1t^R3+Q( ћ@͛D~g -oHT^fҜU)Ԙ8 Z:9 ڰ\ KE,OI$$=&&&@Ǜw/t[o9vq3s$k9dyUs gff`paH\2uKx e/-l )},ZB  4:KḘ:K R-QC@+I.̦El{vxI pH㢚/^E̓cܓjH$/-ԩ믿M/sGs0|Cǿ pMə8s8CwUٲU(t\h3u;w7,*iiVUpzӇ?=ubxsz>^7GL"N:V1ٖSnK@rĈ8k̜d2%fQHM> -vm˲x{g8MS\Q΋,X:w@]Ɋu'5iV#v , b(94Gb(\ȃ?)֌78x>O~3u1}6+X8$8ky4SqbH>)`cV0JzZRWj*ߧEm[}uX63X^@yIac2(=r)T2uאr@V#!3Y;tZe]q-%b<2puW$;'Y<1fڼ_EtF]  ҁoaKJ%8#@X8-}͵tf7ʗ;'.=!O('SǙ|^n[̶g3?+-:p"t^fKMR@6E%Vl%ygykIzݫc笔;zTWBS,frlpL2 ma`KK<`V2(K.RcqM%`[@355ުyz?.#+ˊx4xjkL4fSD,CW9bmڴ_M6]Ooڴzr< XAb$cA.\MmsWl V2: i,k>b\Z+KSDudQby]XQ^UC;  "K@・VMe=J,{(hiZ%:yn\uW9iqKPo]شinyӦMcG 3xWo%.pYN8ْZIS09ʞWZz#oc4e<+ !)5MEUXcekD1tmAT*"R.RSq! Jy@dTb_`M(=(_&cKK޲-JRES_}`3YqF%Bϟϋ)D8o"T2dzJTQqeYR @wp`3uqof p@E`3xsҷ_8#'ٸ>_&G?#K)g渧4PjZB~A)2Œ=DZ9+,HE,SשI̘bii>t?{dǃ!4 x+YD͌ 69&'YKK%3H瀄〦U${]B<* 8#ƍn(;00||x +hЫೕ)\@-ILހV%Noyd;K SEޓKK,f!tXܪ.KۂȄ;\" V`~[Vc첞tp+IT/9P\ uАz0zd2vAk;& _K m  -qWEyt̼fƀR%? gtu(8c7cDF{j)'SEQ4&HM`\"z$7 ؛eQ,CtMzahI#ki>N" ңeaUąQMdn_)뜩{;TN)1]ʴJrɁys\`F˗/L]Y ?SdUt,x:3-`y3z @,i⎚A_l7`x0.hBJ{[V*: [zlkҥx:i8k#@G@n뮻6m "̙M6]up-qWkZ:[PfUnN͍׹0'੭AK-e,?R+{@uTK]~NOK"l DC e_2@1#R6j=_e,.-`crk|\c$*? })2r֭#`.:bZ+7M~Iq:&Z[*9+˲Q?s*+C zq'3 %3UC)HOyҸ7{ N[ΤOf33)P2JfM`- W2ɖ 4F*S_2CH#BErLξIL_>}:<ۯs]w ɴni<3}ԘB <1t<3Һ@g?,&::-2ƲԲ>sQT-vV7O7V)]jTEłZ%|rB|6o>9Mnr^jq5Dμi,L:2ZZDf LkcJjd5mvə:\9s 8JnO-q=Z)V ID݈{>k,FGuD 4FK1~Yʥ<9u C zi@)3to"frU2[WRSW"_:L8g9) k8+'2{mݺ}RRK$Gm c-(q_<."9jIfٳjzyrUͤ]Z a紾y=w"l;.Jj2s}r{@DoD[QL{+[Mut-5j!Fd2n^''U<g9* wg<ŕ^e2Cu{E @ E✩d!Cg)|Ө-`]V(hgת.#U} I|6>wր ј88Z6[9VQ .9q_;tk6P%$zy Ef\,Q\sւGoMJJ<_,HiX({qV偾"8ГL݅ Ԓq!r2fz#GW_"nÆ mݺ}S}ぁ_ܾ}{$39ka}t i2hcJ"XƬ;NtHLeT.k 8j< @ I|"3#˾tVNpX Q\J<"%~HgR.3~%in$[q6hoxjehKO5>q#%_>ogϞm:* ޿aÆdmrS@ q1^m x:)1tqZ5HR,7``صձ.(en?ْ}FΫ/K.~gҥM`gMjJ)+13߲);$\K*qG__RaS*V%Vݜra2WsI#JU_y?SR։oݧ(%߁@ I0AvaEl 4:q`Q D%@-biygij~d "%%~cVmL߳,Yg,… -\@1qTLJ$Q>q%KieIx%0րl(,ۊ?-(duY;-fj}@tBm,VEz7`sުt˨aDP{]*D8^4Y~PxgOŰW؆rk6^&S:{l5vXW%qwxxxrnΝ%#` Wܰau<7A'9w~jdڥ[XwIΰ`Q*"tLg-WDw:n.GYQ)y'T.wWw.KUM1ͤe޼Z,sW|`ZuuH H n֭۾}{o_9ui7O027Ood"pMմ+񞳘F} b콭PZX]df1sv_X6sq\"Jjd&ALff^u2}iuS|b_"aiJ/@e] ìZe輰dHD zeӝ"`gI5&MOmԺpLF~uuZƌT/8l:%غu4K AiZ r#+/R-Z/%,QT##L&ny?xӞC E;W.2pi1v`q$țd 2fu/*\g ̰iY `jN2z݁&,1tܹs:zR0۹szJܺuxʥWgh{GVoaQ-nkG1o=Ivp12sD: yutZb_YY :wA] &gY (a 5``jĶ #zM6iZ:h.ulz#_tKk\@:.B:Ϊ$-5~7]iNBU7s.FX6X~@A1L[j* R.v%O%+aRaoM4p:MKB)*kUUN4PcIpyq@G ]ѸvMab͛S% *lQ |F*g1jPJZЬle=";K@tj$))]a=GA [ D2#]ZL>mS5&۶e'YA OSH$@C0^a$uNxZv):d^P`/rFj%fֽ%JC yt23:O#!~@gM]&%dT)'#vж]ן˓z[6RTcs,i{JGH03qd5 iiޱyǔM1眖k13[G_SVJp@oA'ϲL]?89l"t4 .OZRG@@Y SQާ >HHkre< 끴eW)hzfL5'ߧ I0)Ch۷w˖-vܹ~˖-6o޼~ddd͆ #1۷5/}R_Ĩ"?>;gy͵c?I˭SGgjݼZӨoYy%`C ߌx:Y8YhC E7hlJ5ZIkAYdyՙ[Ԩ!R<^CS)wܹ~pppΝ;o޼y= =O)TCY8 zV^]$p<< l1 /HO$f eXYVy\" <˪UCWti[6ըC ЕN^JX<,f 2+gU-9H&V[y iiVZ 3@G TQC$z @@&TueLۮ7l"#񌉸7,3&jY߹Lx陖d]`Xŋ:x\ :dܬ,ꁷE~c-VX׿ܟ}.@HZFJUY<\"2qބ̛d"k kZy=Y̎d"c!JY'S -@'YukB@7.MaI֋<5*Aפ(" E}EN>dYLNT- sWC `9ҵuU({J]/5R&ڤzox"ej zO jeEM[Z"E!R$PGs:{JJ-%J̰عil^~tuyOv@ нQ:Cj !JV-`cM2`TU؂,H2#1tYUȰyZ9tor z( 8J\;22I FV  '&`R~3c*^̤W0fmx҅,h;:-%3K@@˦2UԲYdZ,/--{ md1m8;|h#FX#}xV "6EǰeOJ==td9-k%)ڼ H+y7(^)1vY,$#$ub툹v4ʌ:1tF6P STQ-kAX7Ϙb X^@tJ:r_F`].1ngUM"&.$Ȭ&@=.R~t+NҢ"5)\¶-0bʲw%ce#`I-,7NhGwEc՛o"g܍!!v $ˤZ'tJ y5\R3>Ѣr 8zSд@ Y\$X ^fՄQ":\""Q˨e&_Itob@[fYDŽ91$-FM,$XIrQZ%O wx쭗dʥL iF2XRiTǖa9z)JXdq*kl0@txCKZ9Xno:iqP@@.˪YܙIWmZ(oIGO IxYj,ঁO钋<ג 7Jb(Һ@Yb,asQy(fPE~f~uS@Z{Ec4mSS.^jpބ7S-bYY5yj%`)|,N3",)rj||z#_$ƙ8bx]i5tVgVK̂ltk׍z-es/bằgè@t<$>Y)b w>X9ob:OMjJU"FPS0p3%,]iW?y|| 8J###kFFFlܸqtI}<ᆲ_ƊNz,,yY)\͸\dC E my.C@LbYy\{oTW5mk1ڄ93IB;5u%"+hHE(/^&&&5t/\rcq.BJm]R0%祗j eTX7:+=R^x+Fng[izby]^q>t::\V`@eV3&;qvy^s%^Vy/ͬH#R(Ih\KZtu_o8qtEHL X׺ hNsJ,NC Е\3H:0tDo,ʼ%Bф;,`VZwm'ȤeN"XiY&6>>4 d8+yI7<<ΪB`4֮W\ fHѲܾ$%3JWQE  "/:e] 40ǟC%ћ@.ZNǵ}̊%dEhJ; `C@ {X`IcHedddΝ;SDᩖ9ʺq:`SDTڹdg1\ b{GY@ 5L5֮qrc ]Pg7=&NߒmfjjxZb/Ii4An8˘_{)B$:Rj~'nΝME7}I-(QԌKFK}e,QȘGӋa.-VLʥ"v5tD:orMP-;y&vf}TqFE3|{fYĒ׌ Q%W稖l 7}ĉ%AW7]2R0s%%ח(f3\?=@t@g[bT. QC@& hgJ&~%E6Y.Q^ 5rujmy]p\`[ '''W׈ɣ:Mc:fFl^ĐE̮v,Ik! 袴K^Nx;HD zyhSb̛aU$T~R y:)-@ ^ɤZf:oQϟ#G關+|Zl=2i %h/ha @,=z:JUsC% .]JyYY _VԥTt!&}^>gjv8 ,4p7n\;22Ƈco-t)2%Cu!K,3Lmm tj HiE\j$cqA]H?UGֿN.|$D =~aD.u_tqCqznƍ: "AR_Ve 1(KZ>]s+ێuDZd]v)k8ɂ_l VGKoٴ6#LKZtf, 4 5JȲ'uU/K'iQPZM,d-[#ۂ(3Fi|$XE%b}OJKXI nrYp"Y: (2Ԑr@ƍ:x+;d - o:&+Amm/SWǴO钋puz)XUyB)YK^b4@722frrrnrrr|7n\K5t} uT:'k akɳ.kq 39l/ZC 0/M;};r`hZI+6-N*R.\ˮЕx+oE^VD+hk<\וxekב/H'Ǿ 7ndvܹ~hhhᱷZN[]ˈ+ 3Jf^k^+_^%CGcM$ɦZ1stR!{VJoҥXٚRqo6J&ĥc4v&cunz@XzK\RZeXMybptZ>xvo|Zt2&ڽLjoƪCX߫nƍk90*+N+]Z%=&[`lMwpXo_VtuWW݅L?:ɚ:MRrz݇N3'$S?Qع pˬVdS$3' nBI͈&ֶ-GWQv%5FjUG,:X\9OHDC IH ~Go5=fKzg's~]mg֋EtXPJO*2Ts%:]fezo/ˆEB| `X F6}(b+f>t}i$" ,@WzB0XuXe3*UptMOc4[S]В4wm?x i].1U.-:7hj7g:Ju1iZg笺f6e`l}^:Rk4kco;?HZev=3pO$1pQ[~.ܫ?^ˬ83go"ߒ,UYβ1o]F^t޹{@oDj7+.l 2u~)نnYeiHz2I.ӉGJ}"R.ū!DB*E#e&ϲger\uJZܭK eT.պv 3,[G_fj#eikmߝ, YV@/_&'[DQh09vVS%; kRR+.B,] ϪD?kW^3jMֲ")o K3n +^uQj'gxezh(J_:OD ћB&ݲoiS3u9xl6ԊKS<8b,wjYYFnddd 7R,oh5cB'r }dX2,c)}YCt]<ݻs}.gffc?839"J+cq˚!JXUCoMvLGs)R處{|p񿥆ڠ#P'U-fg@>t%%E@`^gR =Vr{ 3DMueŋ; lٲN^!/-|}d%q:S]+%fYS kտTv<{@;-piX|ƍkwܹi`l[VQ5X_VjP;f%Dr+י@#:V{w g5竷7EQx;'*iN!?`dV3RyH.2:oY { i젷 o)?3NNN7EQh sxrrrJk"|sUo Z`\߻}0G^ .TS6o޼{R3h4#K7cqf‡A#ZAϪhe'D S)MK˨~ΫSNG&Y 5I ȵW:ɾV۲e: EWx#ۮVOYtJH'co;rI A&EOz-~ӟ~R/y%K 'KD|OQue GJ{fVW:|&f ƺyrx눯xir__2߹szn[@TЮ{ҩSjzQdLKϩYz+ٕ|z& r'׫qҥW>x=Eb] 8CR8u2C@ Y3eT4va$sMK$>`Gۏvi7mqmrrr5`ntt5Yb[YzLkĂ"SC_xӻn&!ŗ#`cʕ qIN8x3t֎g.T.vN%$e'_%:޹)QŖSwWfW jWf3#FFFH:ic@ ey VG4 -`^3M263js"~Rz:$4LNN/%#ge"ut;g!g:H݉UIOV=py@"u K&GP,zr IxȚ5MIj E%\Y9ד<2`Ix/Rvq@ׇqKuQec^:f:KqP@@@R*2Q+]yǺѬ2umN3R@41MLLVcG}JiX=<<3urg;D<9DzگJ@q.3\(iR,f=I?EqҥWoolvCCC4: ꀺ|4p[\" Mz wIP &,#!BdF$OL 'Fl HBv/!@g@tc=^-afK=J~skd*09 E ygRߙ9ϟ"eH񌕁0{l JDQ8Nv&b֤ZϮgkjJ kḭ#Jۋm d:1yI2tK4u=: 4ZTFo5C j[h€j{XFS왔ˈ+MC@NJ` x;JJ͈;Z vVk @]R$pٸ7^GӜX\1V35pv?VrG E )K},..]8l ˗goo&i؆Z>tHdAs轁tDcuoVM"ˮgTK'Yzu8Ji_'&&7JK&rܱUsU{[Uk_?Juq~f)췾M[lYMLJV!?q1KA_W]폄8AekɼAW,@c&ecwxۍ&C!`Gc չ/: %f,#Ruc d`,@Jaf2SE+%*uӺJ?SgaY1O-22Sb BIKPeLT.KE.35F@,8e9b]p:7+@W[UV;{sbYJӈc,|4WvR(z33l/39΃ȷ6"CNZs- FT/` yCCC9اҚ9 0G%m2~x%*%@$dX7S-ib(mzHu_եTUo.hmWAbX&_:)"=궮-NSy?.|J%-`P2+I&YL5y^4GL- !/S.9P#;v4m dZu\E Csg=Eƺ@H-eJT/"uTC`nٹ3y̍+)?jkMq ɇԝ?3uMa:(]YC'J C zeIĨTR>ZyN*=qI[]l7 RI xlܸq-bܟVM'''WT.Cf1?ƬPLfcg?TJDP.^sr^p .J%o4G~u~- 8#@GMAϨ\zEHD zc0ɬMm*|*dٴhKʂ)+òmR- T@GFFlٲe+9ڹ4 KvR3}N@GM{Z5&/r1?=q3ZU_+5o'~msoUUF?O?e˖uh "@700J;n=9! J'0͌]\fJGi7lG~g=I/S5FFFh4JK 4@}WT ]uy,F -KhԆWC,-Sŋ?ν[Nv%Ml{K./UsOqg?q0G|O X+99@   2Lu:^:hzD7 Kxi;].sD)m||YC7<<+peKKǁߑ\fL5ߦH$cM2:D'Avֲ40Gʖ?7?j雪Kw4AץVՙ?h69ym[K窓sYcr)Y: iً] 44ʞl\L2-zd Xd2իy@F~W###kx]X=99jxxx𺡡[lYh4z$=p[3: dD'Q#(Ւb|x+ODʘkxi/C@pE.2뭓[)ȨgR&ىw2%RIQbxp!bFFF #d5M2`K_dCѸ;F;e:IJ,fҸ-@Gb4-UoT+ut&{TgMw^ ]mk?W}5՟ Wؿs7n./Uem/'&)zqr+b i(^X @@jaE'Z=ϨBz,M-Q+G13y/ID#9:JR srrrJ֧EC X1y @tMuj{#Kjݣ,0G ] /MWsOt}+*o ~/SoovUsF67_t#t'yg.MEd4Nj9S.9ԄQ,7 UR MiX3 (b2 CYǕwK8_툧x\r@-y=OY344zƍ | (jb.{,:̨eS*5uKɵ?Vʝb.z-#߹D9w@Sg7Uܪ^]ѿ^ysi? Zέ~W]_=u?+Ϗ+:x~@7O:L%,gxdϨ\z5tDdM2@O# #/N# l/?ŭ׫jPm p;v4;99R022[M@%R躮VG2˨Ynin1Q4ܹsr y5:x./5kfOmhZv{bbrjWѸv.=Ki='r@ J d4̲d% ىwr_&2\i[S 2;99CGsk9x<%ɓh^y핮((FY}wxnKkoK[::'RӺKZhd${踲%ž}n:t?Ǚ:rwm1OFC 0e&cىevMLK7Q-9_JQ &MDqv 744Ԭ#q2)c#3cm]˥,p'IBAD/Eety̙73/8[G.j$;CչcO?@Ѹqf[FV-8_>9:X]:NL@eLR @ mRT. ECCCI4ehhh5)\8~3{.;)w\@t¦-X\2t:G҅s :uYM9;C?S񺹌LR#@@ dVZw76q̀g\+a#}s;S$ĉQ=GkE}uػ̵JVKG2~d}K:^t󚗧)U.eӧO/J%?JuOeF7zIuanzQ}ݴy;v\C^tR-=NK dַ㋢@ zE+cwIN|s{K&D>#M珏OTS8+Gl nIutЍ^344 V߬)| w}Z@F,ӯ2,k@SϦΑ盀ٳv)'\a#p5z/W;v2Ο? 6\G rҥLR--<*Ve8/dG mjdfN)־L]y3ЎO ɶUk'Յ c?:QY37::z*Z閲nbrj[aO[xt@,s}f^԰fTJ?ы gy`\r@EQ(̙3KW.]8WO}:yϫ75ۂR_wTS:,: 1̓nppp-g"0G#\:v^ď}R?0DQ5͂R-oRe"VZ)\ԟcMO=\$:sSGu koozͱK333wfH;&YQb Q:%ɀՒk5:ƻ:ꖞ8:n]@nQ~toOC !h*M&(,j(5n΀~y:~|ڄKxb'#GW?~R'Ƀ-) ܛo④ǫө6zVe]%טzJyQv72 R^/E’q0Ǚ3gTs+Zǂع۷wÆ qQF2 -T\("Rw0=^MOfg窹gVh[_X󣵙ksffO7ܙS[ƫ7419HQYAX:*:Mu2JɇXs%`4Wyϻ1dn&эnm{ބ1f&s~=vJ0dM;gtmX "uؗ\[0`J̱ };121ycRMs}7)<22HPFg&''WI3wY@m\0hgjY^f5W${xI)HSt9v8;'d8K^t>%UKͪ@fH; ;畚YXi:l L i&|.eis ,;hu;T~t{uxK@H".,h d]Ϝcy>h_:N(|,Iv $F\rhhhY.SdYl[4G4,+͛gř|@w=?3l)t:vŋ:Qydv8#+2%nYGˌi&?hn=X(>ko1~cvd{N m2a+iȲ_ٕ]%<{bU<"ĄIE0Τmܸq-9g8I>d{~o\sfoͻ uEޥuu>U3FM/<`[nYђ'>h#PH`iy{5xRݞd 9hgHfӯe#>TKZJu)]9I$pU Y5u$Bt&&vqa-RK"vN2t^h4K)"^"@O)S1c|iލF 2%+T1qY:7̾[^c:yl3:7,L.(8䯓 g}\4N3rbmM5ɺi3x9nE000.8tKzg5k]OThvNNNҘh-@e.&ԋy`T: eR rHQTךL=Dz5˗/NLQ[\vN9}DŪX8N3e'bM`-Om>';%b *vk`3&}ٓ}b$g!IIh,6OAe:dMx%a3o }*wpIK*6(*#eh "vhKWqJαz+%h Z޶ٚh,0dثbV6gDM\N ɽZ+S1p~YBN^ڗoii)PZҹX7vY3mu2/ryH;~U|E Ho-H< jKǯE>yםV7bY"[[옂7ւKIJ8P<$[Gn֭uu-e*˗gk@Ϊ۾}{ҧ5VJvEEѵ*cnz\4M(F FL1{NRw0/lub^;\k^~CmeW4k)dK&MZ(cZ+./N4/MW&!TۧTMb,uL dy'0,j#(DX(; d~-"PKDh_~|Eѩ1cQWs-(W'߫1u2-ԮT<?*S+4K:sQݜ:qK[:/RR/=f.2$_Im;J6Nb6;;X`)~ }7&S]y&R._Zi]t]XǣE:K͐[71X>sA =ʢGݪ㳀h露6]4ɻ4$#(=itXV^{N_Lj˞p gF`GbR۾}{ iunhhS?p/^?s̳S8R@-0'kcjb2Snnw3u]j띾lirB9/XNPT߿Ǹa]k~k灢R84|ke6:m;?A 7&.>,A Dā duB>OEp(@NX@?ikC? 0G]N;2ؚ&c\@ڡC>zСNL'N8qr̙3Ϟ9sٟ?qďuС }Pw &ڢ)XZγ)hT˨g-ePl?XM3qqލҚX?zQ)o{|tl:[]m[Y%L;h7)cʷDžF=Y&>䄝 x ZRɅPV6-O4@xMoHdJ3օGDQ:VKsLc|O5O92EסYb)kF@yiӦj< 6\GF@Wl5lf.$ЕxFOjzW]ڽ9, ֻeo@`9VQ7(s %=߽E~OyUϕPSd[Iu堆/O'[4;-Y hidqd",-bF{_j,.tjkK)-:Yvy`N2̜I섡xWȶz]Uej,ճ̄J%)t>\(N"کAr)إl_4U s~Vjlm;[_]km,5參|"wXĺ7LߔRz@ψ&Ӯ[nkr`I {IQP7.0AENcgtoEG[-wRvȓkeܦ~I@9S g2.b0KYXN%V %FѤ g%5KtnpYjat#LT:j׏wN̵։JkWNB(9^yMr qV!7vL4(7a̸3,l+M x!7~nH.S.VkESoַH@GTf+)_xtј8o|+aoJAn_2f`K)g)dJ` q%LF2& 8H״p?99(Hqe]we ]=Wj:d, Ygrdku|*|佧L2œkIyj1G^AmEQ[n9nYAFn'Y& m k&ڛz0uWIlڙa#K&E\i2bwT y&V,uzMSԎAjؓj|Ϥj RET:ɦ1ckSM)ZMgdfFڭ[OcѷLєDYd@JN@$==L5Z`ZGƤڍ(sSX׵vV4n Κh[S5^V>-)̢etIkRoiMNm*f2ObQ4{"ր |uR)ז sn+@xi-^6XR)4I-]2& G4UHrXdRDEB=YK+ ?^ua)"R9J%)zAuAUE%3N~Vkutھj[۲@7>cej3u&K#F%c?J.Ud=003!'vK:Y9"&U#Zh`"]M.WzstR,w"+sZʤެꪕf+oX]RslkrueQ7%SZI__X"^Bɦ+5^1rˀ*j9X)]5ѾZד^1w_#:Y5k0O\ÓiV\IP)d6]Е^_\zRJ$ף7,% r7:y-tE*uaٔ6+ssϾ/{nVf"MK02BYP1WDRF4"*(I͜wYb]a;鶥_+?^-3ҋ3qx[sqP4n) EW|_<G#) m.s1zEQ$gW. }ig0uP'd`fK&*o.}oFX;Y`"TLfфTMS|hf*jߩ h@ 9,ơnM _D@Ne!KkJ@n) KQTH@R5?bJ<8 <XڱVS8yqF)S:=W,;Ǒ,s9~5 d$ݽ@~j,UY$H+G<év=(3 X#$* Wi;Ii[iƾ}%pk*kt[m SgjnQk.Ru?UХVVy2 iG|g]Ipk7TS'drjBs$m')(Jw3X*{r'NUMx~ޤ.QE;3ϽƵ, Muv6M̓0,ƓEݩīOTM 6uJ#tI$w $QqW|Z<6pN8۔lLQT;id&]r:7Oz%dJ}LAd5Mp::'܂9^;9wH溁bw]^z}ݴTm˻S-955~GߝaxDw]v?𪡸Jݬ)eSK܊*z'.3m . ՌN:l5W)Ǻ륳>W9|\P)TI©ԶfP}7:P;rJt [קSܻclrmL 76-HM;zchd*dwp7źZ;a6GNۦުV4"5\O\BOzՍiW[:ֽ;=n R9VEfӉOdB qMJ9Qw90n E?"UNNm,Z6иH sQ[X7و2P~ 6JM+wNuDi][rbۀ-T)aLW.yK6MnZ:_ sI4j]j2R>S3n]=$t6iNmQz=9 VwDiʍHU{7N;O,tlTӨM&!I'Lo퓩HHD]gmicq%u]nrKoA Dqi<d遛Y}:$KG.S;_Nv@IuBϹu^uIw"^.un5OO[t$7wޜpt^KA` &tEFj־mYv3{lҌ<Qw.mc0m.ؓǪTQ&a7]S"Q57l{n;KŚou i:AQWijJ=Lzm?Mti3mO5D=6m&j낤6ΩL@1:7!U* :q8Mcv+.9Sߢ= GkU+_];c0t/5WW{L;:iӥrtm U]*'N9\W3G%@ɹN4d"FJ<گ;TѤ֭|7Np)6T!WSks:AfAV)SUd)aVBbrY &%Ur) B'6NWq۝cxnq\* }9U}tb6mNER>t@YԹH8y6:3&ى4m=7uDѶ.ם wޕhF8 @1qWݿ\ijKjTd{@ *rqj PuwH@1: N0uFJ!L3\'Rz$ϐ+t XR 4Avꦩ_w>AE0:AxC`0#zuѱ'ST".:y>e J$ 9ZO(IENDB`admin/assets/img/twitter-icon.svg000064400000003375150515074560013103 0ustar00 admin/assets/css/oembeds.css000064400000040364150515074560012075 0ustar00/* * oEmbeds CSS TABLE OF CONTENTS * * 1.0 - GLOBAL * 2.0 - HEADER * 3.0 - 3.0 - OEMBEDS CONTAINER * 3.1 - SECTION HEADER * 3.2 - OEMBED ENABLE/DISABLE BOX * 3.3 - OEMBED INFORMATION BOX * 4.0 - MODAL STYLE * 5.0 - STICKY WIDGET * 6.0 - RESPONSIVENESS */ /*** 1.0 - GLOBAL ***/ .clearfix { display: inline-block; } /* start commented backslash hack \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } .checkmark { width: 21px; height: 22px; border-radius: 50%; display: block; stroke-width: 2; stroke: #fff; stroke-miterlimit: 10; stroke-dashoffset: 0; transform: translate(0px, -3px); } #sbi-oembeds { -webkit-font-smoothing: antialiased; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; } #wpcontent { padding-left: 0px; } #wpbody-content { padding-bottom: 40px; } .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } .sbi-fb-full-wrapper{ padding: 0 53px; padding-top: 82px; } .sbi-fb-fs { width: 100%; position: relative; float: left; box-sizing: border-box; } /*orange*/ .sb-btn-orange{ background: #FE544F!important; color: #fff!important; } .sb-btn-orange:hover{ background: #EC352F!important; color: #fff!important; } .sb-btn-orange:focus, .sb-btn-orange:active{ background: #BC120E!important; color: #fff!important; } /*** 2.0 - HEADER ***/ .sbi-fb-create-ctn{ margin-top: 90px; } .sbi-fb-header{ height: 64px; position: absolute; display: flex; flex-direction: row; justify-content: space-between; align-items: center; background: #fff; padding: 0px 52px; z-index: 2; } .sbi-fb-header-left { display: flex; } .sbi-fb-header-left .sb-social-wall-link-wrap { margin-left: 30px; } .sb-social-wall-link-wrap { display: flex; font-size: 14px; margin: 10px 0; } .sb-social-wall-link { padding: 0 12px; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link:first-child { padding-left: 0; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link:last-child { border-right: none; } .sb-social-wall-link a { text-decoration: none; } .sb-social-wall-link a:focus { outline: none; box-shadow: none; } .sbi-fb-hd-logo{ display: flex; vertical-align: middle; align-items: center; gap: 5px; } .sbi-fb-hd-logo .sb-logo-letters-wrap { margin-bottom: 4px; } .sbi-fb-hd-logo .breadcrumb-title{ font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: 0em; margin-left: 4px; } .sbi-fb-hd-logo .separator{ margin: 0 5px 0 10px; } .sbi-fb-hd-btn{ height: 38px; cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 0px 15px 0px 16px; font-weight: 600; font-size:14px; color: #353A41; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; position: relative; text-decoration: none; transition: all 0.15s ease-in-out; } .sbi-fb-hd-btn:focus { outline: none; box-shadow: none; } .sbi-fb-hd-btn:hover { color: inherit; background-color: #fff; } .sbi-fb-hd-btn i{ margin: 0px 5px; } .sbi-fb-hd-btn[data-icon="left"]{ padding-right: 20px!important; } .sbi-fb-full-wrapper .section-header h1 { font-size: 32px; line-height: 40px; } /*** 3.0 - OEMBEDS CONTAINER ***/ .sbi-oembeds-container { max-width: 875px; position: relative; margin: auto; margin-top: 33px; box-sizing: border-box; } /*** 3.1 - SECTION HEADER ***/ .sbi-section-header h3 { font-weight: 600; font-size: 32px; line-height: 40px; color: #141B38; margin: 0 0 5px 0; } .sbi-section-header p { font-size: 13px; line-height: 18px; color: #434960; margin: 0; } .sbi-oembed-plugin-box { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); margin-bottom: 10px; padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; } /*** 3.2 - OEMBED ENABLE/DISABLE BOX ***/ .sbi-oembed-plugin-box-group { margin-top: 35px; } .sbi-oembed-plugin-box .oembed-text{ flex-basis: 645px; } .sbi-oembed-plugin-box .sbi-oembed-btn{ flex-basis: 125px; text-align: right; } .sbi-oembed-btn .sbi-btn { border-radius: 2px; padding: 10px 20px; border: 0px; color: #fff; font-size: 14px; cursor: pointer; transition: all .15s ease-in-out; box-sizing: border-box; text-decoration: none; align-items: center; display: flex; align-items: center; height: 38px; float: right; } .sbi-oembed-btn .sbi-btn span { margin-right: 5px; height: 15px; width: 15px; } .sbi-oembed-btn .sbi-btn svg { width: 100%; height: 100%; } .sbi-oembed-btn button:hover { background-color: #0096CC; border-color: #0096CC; } .sbi-oembed-btn .sbi-btn:focus, .sbi-oembed-btn .sbi-btn:active { outline: none; box-shadow: none; } .sbi-oembed-btn button.disable-oembed { background: #D72C2C; } .sbi-oembed-btn button.disable-oembed:hover { background-color: #DF5757; border-color: #DF5757; } .sbi-oembed-btn button.disable-oembed:focus, .sbi-oembed-btn button.disable-oembed:active { background-color: #841919; border-color: #841919; } .sbi-oembed-btn button.loading svg { height: 14px; transform: translate(0, 2px); } /*** 3.3 - OEMBED INFORMATION BOX ***/ .sbi-oembed-information { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); margin-bottom: 10px; } .sbi-oembed-information .sb-box-header { padding: 16px 20px; border-bottom: 1px solid #E8E8EB; } .sbi-oembed-information .sb-box-header h3 { margin: 0; font-weight: 600; font-size: 18px; line-height: 140%; color: #141B38; } .sb-two-column-box { display: flex; justify-content: space-around; align-items: center; border-bottom: 1px solid #E8E8EB; } .sb-two-column-box-1 img { max-width: 438px; } .sb-two-column-box-2 img{ margin-top: 20px; max-width: 442px; } .sb-two-column-box .sb-embed-info-text { padding: 0 75px 0 35px; } .sb-two-column-box-2 .sb-embed-info-text { padding: 0 65px 0 30px; } .sb-two-column-box h4, .sb-one-column-box h4 { font-size: 16px; font-weight: 600; line-height: 26px; color: #141B38; } .sb-one-column-box { max-width: 405px; margin: auto; text-align: center; } .sb-one-column-box h4 { padding: 0; margin-top: 30px; margin-bottom: 0px; } .sb-one-column-box p { font-size: 14px; line-height: 22px; } .sb-one-column-box img { margin-top: 15px; margin-bottom: -21px; max-width: 392px; } .sb-two-column-box-1 .sb-left { padding-left: 20px; } .sb-plugin-info-box { padding-top: 20px; } .sb-plugin-info-box .sb-left { padding-left: 35px; } .sb-plugin-info-box .sb-right { padding: 0 60px 0 40px; } .sb-plugin-info-box h4 { font-size: 18px; margin: 0px; } .sb-plugin-info-box p { font-size: 14px; line-height: 22px; color: #434960; margin-top: 10px; } .sb-plugin-info-box img { max-width: 414px; margin-bottom: -5px; } /*** 4.0 - MODAL STYLE ***/ .sbi-oembed-modal { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.4); z-index: 9; } .sbi-modal-content { background-color: #fff; height: 381px; max-width: 572px; padding: 40px 75px 48px; box-sizing: border-box; position: relative; text-align: center; margin: 260px auto 0; } .sbi-modal-content h2 { font-size: 24px; line-height: 29px; text-align: center; letter-spacing: 0; color: #141B38; margin: 0 0 5px 0; } .sbi-modal-content p { font-size: 12px; line-height: 18px; text-align: center; color: #434960; } .sbi-modal-content .cancel-btn{ background: none; border: none; color: #141B38; position: absolute; top: 16px; right: 16px; padding: 0; cursor: pointer; } .sbi-modal-content .modal-icon{ margin-bottom: 45px; } .sbi-modal-content .modal-icon img { max-width: 102px; } .sbi-modal-content .sb-action-buttons{ display: flex; justify-content: center; margin-top: 30px; } .sbi-modal-content .sb-action-buttons button:not(:last-child) { margin-right: 7px; } .sb-action-buttons .sbi-btn { display: flex; align-items: center; vertical-align: middle; justify-content: center; background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; padding: 7px 30px; font-weight: 600; font-size: 14px; line-height: 22px; color: #141B38; box-sizing: border-box; letter-spacing: 0.2px; cursor: pointer; min-width: 175px; } .sb-action-buttons .sbi-install-btn { background-color: #FE544F; border-color: #FE544F; color: #fff; } .sb-action-buttons .sbi-install-btn:disabled { background: #F3F4F5; border: 1px solid #DCDDE1; color: #141B38; cursor: not-allowed } .sb-action-buttons .sbi-install-btn:not(.success):disabled path { fill: #141B38; } .sb-action-buttons .sbi-install-btn span { margin-right: 10px; } .sb-action-buttons .sbi-install-btn.loading svg { height: 16px; transform: translate(0, 2px); } /*** 5.0 Sticky Widget ***/ .sbi-stck-wdg{ position: fixed; right: 21px; z-index: 9; bottom: 20px; } .sbi-stck-wdg-btn{ width: 52px; height: 52px; background: #fff; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; filter: drop-shadow(0px 9px 13px rgba(0, 0, 0, 0.2)); } .sbi-stck-wdg-btn svg{ width: 25px; fill: #FE544F; height: 33px; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls, .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls svg{ display: block; } .sbi-stck-wdg-btn-cls{ width: inherit; height: inherit; position: relative; color: #364152; box-shadow: 0px 1px 6px rgb(0 0 0 / 5%), 0px 9px 12px rgb(0 0 0 / 5%); border-radius: 70px; } .sbi-stck-wdg-btn-cls svg { width: 14px; height: 14px; position: absolute; top: 50%; right: 0; bottom: 0; left: 50%; margin-top: -7px; margin-left: -7px; } .sbi-stck-pop{ position: absolute; width: 292px; height: auto; background: #fff; border: 1px solid #E2E8F0; box-sizing: border-box; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 3px 14px rgba(0, 0, 0, 0.12); border-radius: 2px; padding: 20px; right: 0px; bottom: 66px; color: #141B38; padding-bottom: 82px; } .sbi-stck-wdg[data-active="true"] .sbi-stck-pop{ bottom: 66px; opacity: 1; visibility: visible; } .sbi-stck-pop svg{ fill: currentColor; } .sbi-stck-el-list{ border: 1px solid #DCDDE1; border-radius: 2px; } .sbi-stck-el{ display: flex; align-items: center; padding: 11px 13px; border-bottom: 1px solid #DCDDE1; transition: background .15s ease-in-out; font-size: 12px; } .sbi-stck-el:hover{ background: #F3F4F5; } .sbi-stck-el:last-of-type{ border-bottom: 0px; } .sbi-stck-el-list .sbi-chevron svg{ width: 5px; height: 8px; } .sbi-fs-a { width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0; z-index: 1; } .sbi-stck-el .sbi-stck-el-txt{ color: #27303F; } .sbi-stck-el.sbi-stck-el-upgrd{ padding: 9px 14px; font-size: 14px; background: var(--cl-orange); color: #fff; position: relative; transition: background .15s ease-in-out; font-weight: 600; } .sbi-chevron { position: absolute; right: 14px } .sbi-stck-el.sbi-stck-el-upgrd .sbi-stck-el-txt{ color: #fff; } .sbi-stck-el.sbi-stck-el-upgrd:after{ top: 20px; opacity: 1; } .sbi-stck-el-icon{ margin-right: 10px; } .sbi-stck-el-icon svg{ width: 17px; float: left; } .sbi-stck-title{ margin-top: 20px; margin-bottom: 10px; color: #141B38; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-stck-follow{ background: #F3F4F5; margin-top: 20px; left: 0px; bottom: 0px; position: absolute; padding: 12px 20px; display: flex; align-items: center; } .sbi-stck-follow span{ font-weight: 600; font-size: 14px; } .sbi-stck-flw-links{ display: flex; justify-content: center; align-items: center; margin-left: auto; } .sbi-stck-flw-links a{ width: 36px; height: 28px; color: inherit; display: inline-flex; justify-content: center; align-items: center; margin-left: 4px; border-radius: 2px; transition: background .15s ease-in-out; } .sbi-stck-flw-links svg{ width: 17px; color: #141B38; } .sbi-stck-flw-links a:hover{ background: #fff; } .sbi-stck-flw-links a:hover svg{ color: inherit; } /*** 6.0 - RESPONSIVENESS ***/ @media (max-width: 1170px) { .sbi-oembed-plugin-box .oembed-text { flex-basis: 78%; } } @media (max-width: 1024px) { .sbi-oembed-plugin-box .oembed-text { flex-basis: 72%; } .sb-two-column-box { flex-direction: column; } .sb-two-column-box-1 { flex-direction: column-reverse; } .sb-two-column-box .sb-embed-info-text{ padding: 0 35px; text-align: center; } .sb-two-column-box-2 img { margin-top: 0px; } .sb-two-column-box .sb-left, .sb-two-column-box .sb-right { max-width: 405px; margin: auto; } .sb-two-column-box.sb-plugin-info-box .sb-embed-info-text { margin-top: 25px; } .auto-fold #wpcontent { padding-left: 0px; } } @media (max-width: 767px) { .auto-fold #wpcontent { padding-left: 0; } .sbi-fb-full-wrapper { padding: 70px 20px 0 20px; } .sbi-fb-header { padding: 0px 20px; } .sbi-fb-hd-btn { padding: 0px 15px 0px 7px; } .sbi-about-box .sb-team-info { padding: 30px; } .sbi-oembed-plugin-box { flex-wrap: wrap; } .sbi-oembed-plugin-box .oembed-icon { width: 20px; vertical-align: middle; display: flex; } .sbi-oembed-plugin-box .sbi-oembed-btn { flex-basis: 114px; text-align: left; margin-top: 15px; } .sbi-oembed-plugin-box .oembed-text { flex-basis: calc(100% - 40px); } .sb-plugin-info-box .sb-left, .sb-two-column-box-1 .sb-left, .sb-two-column-box-2 .sb-right, .sb-one-column-box img { display: none; } .sb-one-column-box { padding-bottom: 5px !important; } .sb-one-column-box h4 { margin-top: 21px; } .sb-two-column-box.sb-plugin-info-box .sb-embed-info-text { margin-top: 0; } .sb-plugin-info-box p { margin-bottom: 17px; } .sbi-modal-content { margin: 80px auto 0; width: 90%; height: auto; padding: 40px 30px; } .sbi-modal-content .modal-icon { margin-bottom: 30px; } .sb-plugin-info-box h4 { font-size: 16px; } } @media (max-width: 630px) { .sb-two-column-box img, .sb-one-column-box img { max-width: 100%; } .sbi-modal-content .sb-action-buttons { flex-direction: column; } .sbi-modal-content .sb-action-buttons button:not(:last-child) { margin-right: 0px; margin-bottom: 7px; } } @media (max-width: 530px) { .sb-two-column-box .sb-left, .sb-two-column-box .sb-right, .sb-one-column-box { padding: 0 20px; } .sb-two-column-box h4, .sb-one-column-box h4 { line-height: 22px; } .sb-one-column-box img { margin-bottom: -15px; } } .sbi-btn-blue { background: #0068A0!important; color: #fff!important; } .sb-button-standard{ position: relative; font-style: normal; font-weight: 600; font-size: 14px; padding: 10px 20px 10px 39px; line-height: 16px; height: auto; } .sb-button-standard svg { width: 16px; height: 16px; position: absolute; left: 13px; right: auto; top: 10px; bottom: auto; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } admin/assets/css/support.css000064400000060060150515074560012166 0ustar00/* * SUPPORT PAGE CSS TABLE OF CONTENTS * * 1.0 - GLOBAL * 2.0 - HEADER * 3.0 - 3.0 - SUPPORT CONTAINER * 3.1 - SECTION HEADER * 3.2 - SUPPORT BLOCK * 3.3 - CONTACT SUPPORT BLOCK * 4.0 - STICKY WIDGET * 5.0 - SB NOTIFICATION ELEMENT * 6.0 - RESPONSIVENESS */ /*** 1.0 - GLOBAL ***/ .clearfix { display: inline-block; } /* start commented backslash hack \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } #sbi-support { -webkit-font-smoothing: antialiased; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; } #wpcontent { padding-left: 0px; } #wpbody-content { padding-bottom: 40px; } .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } /*orange*/ .sb-btn-orange{ background: #FE544F!important; color: #fff!important; } .sb-btn-orange:hover{ background: #EC352F!important; color: #fff!important; } .sb-btn-orange:focus, .sb-btn-orange:active{ background: #BC120E!important; color: #fff!important; } .sbi-fb-cp-clpboard{ width: 0px; height: 0px; position: absolute; left: -100000px; } .sbi-fb-full-wrapper{ padding: 0 53px; padding-top: 82px; } .sbi-fb-fs { width: 100%; position: relative; float: left; box-sizing: border-box; } #adminmenu a[href="admin.php?page=sbi-support"] { display: none; } .sb-btn-grey:not(:disabled){ background: #F3F4F5!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sb-btn-grey:not(:disabled):hover{ background: #fff!important; color: #141B38!important; border: 1px solid #DCDDE1!important; } .sb-btn-grey:not(:disabled):focus, .sb-btn-grey:not(:disabled):active{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } /*** 2.0 - HEADER ***/ .sbi-fb-create-ctn{ margin-top: 90px; } .sbi-fb-header{ height: 64px; position: absolute; display: flex; flex-direction: row; justify-content: space-between; align-items: center; background: #fff; padding: 0px 52px; z-index: 2; } .sbi-fb-header-left { display: flex; } .sbi-fb-header-left .sb-social-wall-link-wrap { margin-left: 30px; } .sb-social-wall-link-wrap { display: flex; font-size: 14px; margin: 10px 0 10px 30px; } .sb-social-wall-link:first-child { padding-left: 0; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link { padding: 0 12px; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link a { text-decoration: none; } .sb-social-wall-link a:focus { outline: none; box-shadow: none; } .sb-social-wall-link:last-child { border-right: none; } .sbi-fb-hd-logo{ display: flex; vertical-align: middle; align-items: center; gap: 5px; } .sbi-fb-hd-logo .sb-logo-letters-wrap { transform: translate(0px, -2px); } .sbi-fb-hd-logo .breadcrumb-title{ font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: 0em; margin-left: 4px; } .sbi-fb-hd-logo .separator{ margin: 0 5px 0 10px; } .sbi-fb-hd-btn{ height: 38px; cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 0px 15px 0px 16px; font-weight: 600; font-size:14px; color: #353A41; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; position: relative; text-decoration: none; transition: all 0.15s ease-in-out; } .sbi-fb-hd-btn:focus { outline: none; box-shadow: none; } .sbi-fb-hd-btn:hover { color: inherit; background-color: #fff; } .sbi-fb-hd-btn i{ margin: 0px 5px; } .sbi-fb-hd-btn[data-icon="left"]{ padding-right: 20px!important; } .sbi-fb-full-wrapper .section-header h1 { font-size: 32px; line-height: 40px; } /*** 3.0 - SUPPORT CONTAINER ***/ .sbi-sb-container { max-width: 885px; position: relative; margin: auto; margin-top: 33px; box-sizing: border-box; } /*** 3.1 - SECTION HEADER ***/ .sbi-section-header { display: flex; justify-content: space-between; align-items: center; } .sbi-section-header h2{ font-weight: 600; font-size: 32px; line-height: 40px; color: #141B38; margin: 0; } .sbi-section-header .sbi-search-doc .sbi-search-doc-field { position: relative; background: #fff; border: 1px solid #DCDDE1; min-width: 283px; box-sizing: border-box; height: 38px; padding: 0px 14px 0px 15px; font-weight: 600; font-size: 14px; line-height: 22px; color: #141B38; text-decoration: none; margin-right: 1px; } .sbi-section-header .sbi-search-doc .sbi-search-doc-field .sb-btn-input { height: 100%; border: none; outline: none; background-color: transparent; margin-left: 25px; color: #141B38; min-width: 200px; transform: translateY(-1px); } .sbi-section-header .sbi-search-doc .sbi-search-doc-field .sb-btn-input::placeholder { color: #141B38; } .sbi-section-header .sbi-search-doc .sbi-search-doc-field:focus, .sbi-section-header .sbi-search-doc .sbi-search-doc-field .sb-btn-input:focus { outline: none; box-shadow: none; } .sbi-section-header .sbi-search-doc .sbi-search-doc-field .sb-btn-icon { position: absolute; left: 15px; top: 11px; cursor: pointer; } .sbi-section-header .sbi-search-doc .sbi-search-doc-field .sb-btn-link-icon{ cursor: pointer; position: absolute; right: 2px; top: 0; width: 35px; text-align: center; height: 100%; padding-top: 9px; box-sizing: border-box; } .sbi-section-header .sbi-search-doc a .sb-btn-link-icon{ margin-left: 56px; } /*** 3.2 - SUPPORT BLOCK ***/ .sbi-support-blocks { margin-top: 22px; display: flex; } .sbi-support-blocks .sbi-support-block { padding: 22px 18px; background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; width: calc(33% - 7px); box-sizing: border-box; position: relative; } .sbi-support-blocks .sbi-support-block:not(:last-child) { margin-right: 14px; } .sbi-support-blocks .sbi-support-block h3 { font-style: normal; font-weight: 600; font-size: 18px; line-height: 25px; color: #141B38; margin-top: 15px; margin-bottom: 0; } .sbi-support-blocks .sbi-support-block p { font-size: 12px; line-height: 18px; color: #64748B; margin-top: 5px; } .sb-block-header img { width: 56px; height: 56px; } .sb-articles-list { margin-top: 31px; margin-bottom: 79px; } .sb-articles-list ul li { position: relative; margin: 0px; padding-right: 10px; } .sb-articles-list ul li:not(:last-child) { border-bottom: 1px solid #E8E8EB; position: relative; } .sb-articles-list ul li a { font-size: 14px; line-height: 22px; color: #141B38; text-decoration: none; display: block; padding: 13px 0; } .sb-articles-list ul li:not(:last-child):after { content: ''; position: absolute; left: 0px; bottom: -1px; background-color: #0068A0; height: 1px; width: 0; transition: all 0.25s ease-in-out; } .sb-articles-list ul li:not(:last-child):hover:after { width: 100%; } .sb-articles-list ul li a:hover { color: #0068A0; } .sb-articles-list ul li .sb-list-icon { position: absolute; right: 0; top: calc(50% - 9px); } .sb-articles-list ul li .sb-list-icon svg { width: 5px; } .sb-articles-list ul li .sb-list-icon svg path { fill: #8C8F9A; } .sbi-support-blocks .sbi-sb-button { margin-top: 50px; position: absolute; left: 0; bottom: 20px; width: calc(100% - 40px); padding: 0 20px; } .sbi-support-blocks .sbi-sb-button .sb-btn-icon { margin-left: 8px; } .sbi-support-blocks .sbi-sb-button .sb-btn-icon svg { width: 5px; transform: translateY(0px); margin-left: 3px; } .sbi-support-blocks .sbi-sb-button a { background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; font-weight: 600; font-size: 12px; line-height: 19px; color: #141B38; display: block; text-align: center; text-decoration: none; padding: 6px; transition: all 0.15s ease-in-out; } .sbi-support-blocks .sbi-sb-button a:hover, .sbi-section-header .sbi-search-doc a:hover { background: #FFFFFF; border: 1px solid #D0D1D7; } .sbi-support-blocks .sbi-sb-button a:focus, .sbi-support-blocks .sbi-sb-button a:active, .sbi-section-header .sbi-search-doc a:focus, .sbi-section-header .sbi-search-doc a:active { background: #E8E8EB; border: 1px solid #D0D1D7; } /*** 3.3 - CONTACT SUPPORT BLOCK ***/ .sbi-support-contact-block { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; padding: 20px 20px 23px; margin-top: 28px; box-sizing: border-box; margin-bottom: 12px; display: flex; } .sbi-support-contact-block .sb-cb-content h3{ font-size: 24px; line-height: 29px; color: #141B38; margin: 0; margin-bottom: 16px; } .sbi-support-contact-block .sb-cb-icon { margin-right: 30px; } .sbi-support-contact-block .sb-cb-icon span{ background: #E8E8EB; border-radius: 60px; width: 68px; height: 68px; display: inline-block; text-align: center; padding-top: 22px; box-sizing: border-box; } .sbi-support-contact-block .sb-cb-btn{ background: #FE544F; border-radius: 2px; color: #fff; text-decoration: none; display: inline-block; padding: 8px 12px; font-size: 14px; } .sbi-support-contact-block .sb-cb-btn:hover { background: #EC352F; border-color: #EC352F; } .sbi-support-contact-block .sb-cb-btn:focus, .sbi-support-contact-block .sb-cb-btn:active { background: #BC120E; border-color: #BC120E; outline: none; box-shadow: none; } .sbi-support-contact-block .sb-cb-btn span { margin-left: 11px; } .sbi-support-contact-block .sb-cb-btn svg { width: 5px; } .sbi-support-contact-block .sb-cb-btn path { fill: #fff; } .sbi-support-contact-block .sb-contact-block-left{ flex-basis: 625px; /* width: 625px; */ /* float: left; */ display: flex; padding-top: 10px; box-sizing: border-box; } .sbi-support-contact-block .sb-contact-block-right { flex-basis: 220px; /* width: 220px; float: left; */ padding-top: 10px; padding-left: 32px; box-sizing: border-box; border-left: 1px solid #DCDDE1; } .sbi-support-contact-block .sb-contact-block-right p { font-size: 12px; line-height: 18px; color: #141B38; } .sbi-support-contact-block .sb-contact-block-right img { max-width: 65px; } /*** 3.4 - SYSTEM INFO BLOCK ***/ .sbi-system-info-section { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; } .sbi-system-info-section .sbi-system-header{ display: flex; padding: 12px 20px 0; justify-content: space-between; } .sbi-system-info-section .sbi-system-header h3 { font-weight: 600; font-size: 18px; line-height: 25px; color: #141B38; margin-top: 9px; } .sbi-system-info-section .sbi-system-header .sbi-copy-btn { background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; font-size: 14px; font-weight: 600; line-height: 22px; color: #141B38; height: 38px; padding: 5px 20px 5px 12px; cursor: pointer; transition: all 0.15s ease-in-out; } .sbi-system-info-section .sbi-system-header .sbi-copy-btn:hover { background: #FFFFFF; border: 1px solid #D0D1D7; } .sbi-system-info-section .sbi-system-header .sbi-copy-btn:focus, .sbi-system-info-section .sbi-system-header .sbi-copy-btn:active { background: #E8E8EB; border: 1px solid #D0D1D7; } .sbi-system-info-section .sbi-system-header .sbi-copy-btn svg { height: 19px; width: 19px; transform: translate(0px, 4px); margin-right: 5px; } .sbi-system-info-section .sbi-system-info { padding: 0 20px 20px; border-bottom: 1px solid #E8E8EB; } .sbi-system-info-section .sbi-system-info .system_info:focus { outline: none; box-shadow: none; } .sbi-system-info-section .sbi-system-info .system_info a { color: #0068A0; } .sbi-system-info-section .sbi-system-info .system_info { box-sizing: border-box; background: #F9F9FA; border: 1px solid #E8E8EB; width: 100%; resize: none; border-radius: 0; padding: 20px 28px; font-size: 12px; line-height: 18px; color: #141B38; width: 100%; height: 123px; font-family: 'Fira Code', monospace; word-break: break-all; } .sbi-system-info-section .sbi-system-info .system_info.expanded { height: 600px; overflow-x: hidden; overflow-y: scroll; } .sbi-system-info-section .sbi-system-info .system_info.collapsed { overflow: hidden; } .sbi-system-info-section .sbi-system-info .sbi-expand-btn { padding: 8px 12px 8px 8px; background: #FFFFFF; border: 1px solid #D0D1D7; border-radius: 2px; font-size: 12px; line-height: 19px; color: #141B38; width: 100%; margin-top: -5px; z-index: 9; position: relative; font-weight: 500; cursor: pointer; transition: all .15s ease-in-out; } .sbi-system-info-section .sbi-system-info .sbi-expand-btn:hover { background: #F3F4F5; border: 1px solid #DCDDE1; } .sbi-system-info-section .sbi-system-info .sbi-expand-btn span { margin-right: 10px; } .sbi-system-info-section .sbi-system-info .sbi-expand-btn:focus, .sbi-system-info-section .sbi-system-info .sbi-expand-btn:active{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sbi-export-settings-section { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; padding: 20px; background: #FFFFFF; display: flex; justify-content: space-between; } .sbi-export-settings-section .sbi-export-right{ display: flex; } .sbi-export-settings-section .sbi-export-left h3 { font-style: normal; font-weight: 600; font-size: 18px; line-height: 25px; color: #141B38; margin: 0 0 4px 0; } .sbi-export-settings-section .sbi-export-left p { font-size: 12px; line-height: 18px; color: #141B38; margin: 0; } .sbi-export-settings-section .sbi-select{ min-width: 234px; border: 1px solid #D0D1D7; padding: 3px 15px; height: 38px; font-size: 14px; color: #141B38; -webkit-appearance: none; appearance: none; margin-right: 8px; background: #fff url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAFCAYAAAB8ZH1oAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABSSURBVHgBfc4hCkAhDAbgjV3slQcvvHuYDWY1G8zewyIWb6YuCCLqD4Pt5wtD54NBQA2XVKiWcorl/X7s+DkhJYUhPk54IN5plCue0Tb8M8/aNx/uIpRVqbbFAAAAAElFTkSuQmCC') no-repeat right 15px top 55%; } .sbi-export-settings-section .sbi-btn { height: 38px; font-size: 14px; padding: 7px 20px 7px 16px; display: flex; align-items: center; vertical-align: middle; background: #F3F4F5; border: 1px solid #DCDDE1; border-radius: 2px; font-weight: 500; transition: all .15s ease-in-out; cursor: pointer; } .sbi-export-settings-section .sbi-btn:disabled { cursor: not-allowed; color: #8C8F9A; background: #F3F4F5; } .sbi-export-settings-section .sbi-btn:disabled:hover { color: #8C8F9A; } .sbi-export-settings-section .sbi-btn span { margin-right: 11px; transform: translate(0px, 2px); } .sbi-export-settings-section .sbi-btn:disabled span path { fill: #8C8F9A; } .sbi-support-contact-block {} /*** 4.0 Sticky Widget ***/ .sbi-stck-wdg{ position: fixed; right: 21px; z-index: 9; bottom: 20px; } .sbi-stck-wdg-btn{ width: 52px; height: 52px; background: #fff; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; filter: drop-shadow(0px 9px 13px rgba(0, 0, 0, 0.2)); } .sbi-stck-wdg-btn svg{ width: 25px; fill: #FE544F; height: 33px; float: left; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls, .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls svg{ display: block; } .sbi-stck-wdg-btn-cls{ width: inherit; height: inherit; position: relative; color: #364152; box-shadow: 0px 1px 6px rgb(0 0 0 / 5%), 0px 9px 12px rgb(0 0 0 / 5%); border-radius: 70px; } .sbi-stck-wdg-btn-cls svg { width: 14px; height: 14px; position: absolute; top: 50%; right: 0; bottom: 0; left: 50%; margin-top: -7px; margin-left: -7px; } .sbi-stck-pop{ position: absolute; width: 292px; height: auto; background: #fff; border: 1px solid #E2E8F0; box-sizing: border-box; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 3px 14px rgba(0, 0, 0, 0.12); border-radius: 2px; padding: 20px; right: 0px; bottom: 66px; color: #141B38; padding-bottom: 82px; } .sbi-stck-wdg[data-active="true"] .sbi-stck-pop{ bottom: 66px; opacity: 1; visibility: visible; } .sbi-stck-pop svg{ fill: currentColor; } .sbi-stck-el-list{ border: 1px solid #DCDDE1; border-radius: 2px; } .sbi-stck-el{ display: flex; align-items: center; padding: 11px 13px; border-bottom: 1px solid #DCDDE1; transition: background .15s ease-in-out; font-size: 12px; } .sbi-stck-el:hover{ background: #F3F4F5; } .sbi-stck-el:last-of-type{ border-bottom: 0px; } .sbi-stck-el-list .sbi-chevron svg{ width: 5px; height: 8px; } .sbi-fs-a { width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0; z-index: 1; } .sbi-stck-el .sbi-stck-el-txt{ color: #27303F; } .sbi-stck-el.sbi-stck-el-upgrd{ padding: 9px 14px; font-size: 14px; background: var(--cl-orange); color: #fff; position: relative; transition: background .15s ease-in-out; font-weight: 600; } .sbi-chevron { position: absolute; right: 14px } .sbi-stck-el.sbi-stck-el-upgrd .sbi-stck-el-txt{ color: #fff; } .sbi-stck-el.sbi-stck-el-upgrd:after{ top: 20px; opacity: 1; } .sbi-stck-el-icon{ margin-right: 10px; } .sbi-stck-el-icon svg{ width: 17px; float: left; } .sbi-stck-title{ margin-top: 20px; margin-bottom: 10px; color: #141B38; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-stck-follow{ background: #F3F4F5; margin-top: 20px; left: 0px; bottom: 0px; position: absolute; padding: 12px 20px; display: flex; align-items: center; } .sbi-stck-follow span{ font-weight: 600; font-size: 14px; } .sbi-stck-flw-links{ display: flex; justify-content: center; align-items: center; margin-left: auto; } .sbi-stck-flw-links a{ width: 36px; height: 28px; color: inherit; display: inline-flex; justify-content: center; align-items: center; margin-left: 4px; border-radius: 2px; transition: background .15s ease-in-out; } .sbi-stck-flw-links svg{ width: 17px; color: #141B38; } .sbi-stck-flw-links a:hover{ background: #fff; } .sbi-stck-flw-links a:hover svg{ color: inherit; } /*** SB NOTIFICATION ELEMENT ***/ .sb-notification-ctn{ position: fixed; bottom: -100px; left: 200px; z-index: 99999; background: #fff; display: flex; justify-content: center; align-items: center; border-left: 3px solid #fff; line-height: 1em; padding: 10px 20px; padding-left: 0px; border-radius: 4px; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); } .sb-notification-ctn[data-active="hidden"]{ -webkit-animation: sbi-notification-hide .5s forwards linear; animation: sbi-notification-hide .5s forwards linear; } .sb-notification-ctn[data-active="shown"]{ -webkit-animation: sbi-notification-show .5s forwards linear; animation: sbi-notification-show .5s forwards linear; } @-webkit-keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @-webkit-keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} @keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} .sb-notification-ctn[data-type="success"]{ border-color: #59AB46; } .sb-notification-ctn[data-type="error"]{ border-color: #D72C2C; } .sb-notification-ctn[data-type="message"]{ border-color: #141B38; } .sb-notification-icon{ width: 25px; height: 25px; display: flex; justify-content: center; align-items: center; margin-left: 10px; margin-right: 15px; } .sb-notification-icon svg{ width: 22px; height: 22px; float: left; fill: currentColor; } .sb-notification-ctn[data-type="success"] .sb-notification-icon{ color: #59AB46; } .sb-notification-ctn[data-type="error"] .sb-notification-icon{ color: #D72C2C; } .sb-notification-ctn[data-type="message"] .sb-notification-icon{ color: #141B38; } .sb-notification-ctn span{ font-size: 14px; color: #141B38; font-weight:500; } /*** 6.0 - RESPONSIVENESS ***/ @media (max-width: 1024px) { .sbi-support-contact-block { flex-direction: column; } .sbi-support-contact-block .sb-contact-block-left, .sbi-support-contact-block .sb-contact-block-right { flex-basis: auto; } .sbi-support-contact-block .sb-contact-block-right { padding-top: 42px; padding-left: 0; border-left: 0px solid #DCDDE1; position: relative; } .sbi-support-contact-block .sb-contact-block-right:before { top: 25px; left: 0; width: 65px; height: 1px; background: #DCDDE1; position: absolute; content: ''; } } @media (max-width: 767px) { .sbi-support-blocks { flex-direction: column; } .sbi-support-blocks .sbi-support-block { width: 100%; margin-bottom: 12px; } .auto-fold #wpcontent { padding-left: 0; } .sbi-fb-full-wrapper { padding: 70px 20px 0 20px; } .sbi-fb-hd-btn { padding: 0px 15px 0px 7px; } .sbi-fb-header { padding: 0px 20px; } .sbi-section-header, .sbi-export-settings-section { flex-wrap: wrap; } .sbi-section-header h2 { margin-bottom: 30px; } .sbi-section-header .sbi-search-doc { width: 100%; } .sbi-export-settings-section .sbi-export-left, .sbi-export-settings-section .sbi-export-right{ width: 100%; } .sbi-export-settings-section .sbi-export-left { margin-bottom: 20px; } .sbi-export-settings-section .sbi-export-right { flex-wrap: wrap; } .sbi-export-settings-section .sbi-select { width: 100%; margin-bottom: 10px; } .sb-notification-ctn { left: 20px; } } @media (max-width: 580px) { .sbi-support-contact-block .sb-contact-block-left { flex-wrap: wrap; } .sbi-support-contact-block .sb-contact-block-left .sb-cb-content { margin-top: 20px; } } @media (max-width: 480px) { .sbi-fb-hd-btn { padding: 0px 10px 0px 7px !important; } .sbi-fb-hd-btn[data-icon="left"] { padding-right: 10px!important; } } .sb-button-standard{ position: relative; font-style: normal; font-weight: 600; font-size: 14px; padding: 10px 20px 10px 39px; line-height: 16px; height: auto; } .sb-button-standard svg { width: 16px; height: 16px; position: absolute; left: 13px; right: auto; top: 10px; bottom: auto; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } admin/assets/css/settings.css000064400000124462150515074560012321 0ustar00/* * Settings CSS TABLE OF CONTENTS * * 1.0 - Global * 2.0 - SBI CSS Framework * 2.1 - Utility CSS * 2.2 - Notification Element * 3.0 - Header * 4.0 - Content * 4.1 - Tab Styles * 4.2 - Tab Boxes * 5.0 - Footer * 6.0 - Sticky Widget * 7.0 - Responsiveness */ /*** 1.0 - Global ***/ .clearfix { display: inline-block; } /* start commented backslash hack \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } #sbi-settings { -webkit-font-smoothing: antialiased; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; } #wpcontent { padding-left: 0px; } .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } .checkmark { width: 21px; height: 22px; border-radius: 50%; display: block; stroke-width: 2; stroke: #59AB46; stroke-miterlimit: 10; stroke-dashoffset: 0; } .sbi-fb-full-wrapper{ padding: 0 53px; padding-top: 82px; } .sbi-fb-fs { width: 100%; position: relative; float: left; box-sizing: border-box; } #adminmenu a[href="admin.php?page=sbi-support"] { display: none; } /*** 2.0 - SBI CSS Framework ***/ .d-flex { display: flex; } .justify-between { justify-content: space-between; } .items-center{ align-items: center; } /* SBI Form Fields */ .sb-form-field { display: block; position: relative; } .sb-form-field .help-text { font-size: 13px; line-height: 22px; color: #434960; font-weight: 400; word-spacing: 0.3px; max-width: 640px; } .sb-form-field .help-text-green { color: #59AB46; } .sb-form-field .help-text a { color: inherit; font-weight: 500; } /* input field styles */ .sb-form-field .sbi-form-field { background: #FFFFFF; border: 1px solid #D0D1D7; box-sizing: border-box; border-radius: 1px; height: 38px; padding: 8px; } .sb-form-field .sbi-form-field:focus { outline: none; box-shadow: none; } .sb-form-field .field-icon { position: absolute; right: 8px; top: 10px; font-size: 20px; } /* sbi-checkbox styles */ .sbi-checkbox { align-items: center; border-radius: 100px; display: flex; font-weight: 700; margin-bottom: 15px; } .sbi-checkbox input[type=checkbox] { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } .toggle-track { width: 36px; height: 20px; position: relative; background: #9e9e9e; border-radius: 31px; } .toggle-indicator { width: 16px; height: 16px; background-color: #fff; border-radius: 100px; top: 2px; position: absolute; left: 2px; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.25); transition: all .3s cubic-bezier(0.23, 1, 0.320, 1); } .sbi-checkbox input[type=checkbox]:checked + .toggle-track .toggle-indicator { left: 18px; } .sbi-checkbox input[type=checkbox]:checked + .toggle-track { background: #0096CC; } .sbi-error-text { color: #D72C2C; } .sbi-error-text a { color: inherit; } .sbi-fb-cp-clpboard{ width: 0px; height: 0px; position: absolute; left: -100000px; } /* sbi-select */ .sb-form-field .sbi-select { min-width: 235px; border: 1px solid #D0D1D7; padding: 8px 35px 8px 15px; height: 50px; font-size: 16px; color: #141B38; -webkit-appearance: none; appearance: none; background: #fff url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAFCAYAAAB8ZH1oAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABSSURBVHgBfc4hCkAhDAbgjV3slQcvvHuYDWY1G8zewyIWb6YuCCLqD4Pt5wtD54NBQA2XVKiWcorl/X7s+DkhJYUhPk54IN5plCue0Tb8M8/aNx/uIpRVqbbFAAAAAElFTkSuQmCC') no-repeat right 15px top 55%; box-sizing: border-box; } .sb-form-field .sbi-select.size-md { width: 422px; } .sb-form-field .sbi-select.size-sm { width: 210px; min-width: 210px; } .sb-form-field .sbi-select.size-xs { min-width: 100px; width: 100px; } .sb-form-field .sbi-textarea { width: 100%; min-height: 100px; padding: 12px; border: 1px solid #D0D1D7; font-size: 16px; } .sb-form-field .sbi-textarea::placeholder { color: #8C8F9A; } .sb-form-field .sbi-textarea:focus { outline: none; box-shadow: none; border-color: #9c9ca0; } /* SBI Buttons */ .sbi-btn { display: flex; align-items: center; vertical-align: middle; background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; padding: 7px 20px; font-weight: 600; font-size: 14px; line-height: 22px; color: #141B38; box-sizing: border-box; letter-spacing: 0.2px; cursor: pointer; transition: all 0.15s ease-in-out; } .sbi-btn:hover { background: #FFFFFF; border: 1px solid #D0D1D7; } .sbi-btn:focus, .sbi-btn:active { background: #E8E8EB; border: 1px solid #D0D1D7; } .sbi-btn .sb-btn-icon { margin-right: 10px; max-width: 15px; } .sbi-btn.sb-btn-lg { height: 50px; font-size: 16px; padding: 7px 25px; } .sbi-btn.sb-btn-blue { background-color: #0068A0; color: #fff; border-color: #096292; } .sbi-btn span { line-height: 1; margin-right: 5px; } .sb-btn-orange { background: #FE544F; color: #fff; font-style: normal; font-weight: 600; font-size: 14px; line-height: 160%; } .sb-tabs-container .sb-tabs .sb-btn-orange { margin-top: -20px; } .sbi-btn svg.checkmark { stroke: #fff; transform: translate(-7px, -3px); } .input-hidden { height: 0px; width: 0px; overflow: hidden; } /*** 2.1 - SBI Utility CSS ***/ .mr-3 { margin-right: 3px; } .mr-4 { margin-right: 4px; } .mb-6 { margin-bottom: 6px; } .mb-10 { margin-bottom: 10px; } .mb-15 { margin-bottom: 15px; } .mb-20 { margin-bottom: 20px; } .mb-30 { margin-bottom: 30px; } .mb-40 { margin-bottom: 40px; } .mb-50 { margin-bottom: 50px; } .ml-10 { margin-left: 15px; } /*** 2.1 Notification Element ***/ .sb-notification-ctn{ position: fixed; bottom: -100px; left: 200px; z-index: 99999; background: #fff; display: flex; justify-content: center; align-items: center; border-left: 3px solid #fff; line-height: 1em; padding: 10px 20px; padding-left: 0px; border-radius: 4px; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); } .sb-notification-ctn[data-active="hidden"]{ -webkit-animation: sbi-notification-hide .5s forwards linear; animation: sbi-notification-hide .5s forwards linear; } .sb-notification-ctn[data-active="shown"]{ -webkit-animation: sbi-notification-show .5s forwards linear; animation: sbi-notification-show .5s forwards linear; } @-webkit-keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @-webkit-keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} @keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} .sb-notification-ctn[data-type="success"]{ border-color: #59AB46; } .sb-notification-ctn[data-type="error"]{ border-color: #D72C2C; } .sb-notification-ctn[data-type="message"]{ border-color: #141B38; } .sb-notification-icon{ width: 25px; height: 25px; display: flex; justify-content: center; align-items: center; margin-left: 10px; margin-right: 15px; } .sb-notification-icon svg{ width: 22px; height: 22px; float: left; fill: currentColor; } .sb-notification-ctn[data-type="success"] .sb-notification-icon{ color: #59AB46; } .sb-notification-ctn[data-type="error"] .sb-notification-icon{ color: #D72C2C; } .sb-notification-ctn[data-type="message"] .sb-notification-icon{ color: #141B38; } .sb-notification-ctn span{ font-size: 14px; color: #141B38; font-weight:500; } /*** 3.0 - Header ***/ .sbi-fb-create-ctn{ margin-top: 90px; } .sbi-fb-header{ height: 64px; position: absolute; display: flex; flex-direction: row; justify-content: space-between; align-items: center; background: #fff; padding: 0px 52px; z-index: 2; } .sbi-fb-header-left { display: flex; } .sbi-fb-header-left .sb-social-wall-link-wrap { margin-left: 30px; } .sbi-fb-hd-logo{ display: flex; vertical-align: middle; align-items: center; gap: 5px; } .sbi-fb-hd-logo .sb-logo-letters-wrap { margin-bottom: 4px; } .sbi-fb-hd-logo .breadcrumb-title{ font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: 0em; margin-left: 4px; } .sbi-fb-hd-logo .separator{ margin: 0 5px 0 10px; } .sbi-fb-hd-btn{ height: 38px; cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 0px 15px 0px 16px; font-weight: 600; font-size:14px; color: #353A41; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; position: relative; text-decoration: none; transition: all 0.3s ease; } .sbi-fb-hd-btn:hover { color: inherit; background-color: #fff; } .sbi-fb-hd-btn i{ margin: 0px 5px; } .sbi-fb-hd-btn[data-icon="left"]{ padding-right: 20px!important; } .sbi-fb-full-wrapper .section-header { margin-top: 33px; } .sbi-fb-full-wrapper .section-header h1 { font-size: 32px; line-height: 40px; } /*** 4.0 - Content ***/ /*** 4.1 - Tab Styles ***/ .sb-tabs-container { position: relative; width: 100%; margin-top: 28px; } .sb-tabs-container .sb-tab-content .sb-tab-content-inner { width: 100%; margin-top: 20px; height: auto; padding-bottom: 30px; } .sb-tabs-container .sbi-save-button { display: flex; justify-content: flex-end; margin-top: 30px; } .sb-tabs-container .sb-tabs { position: relative; display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; } .sb-tabs-container .sb-tabs:after { position: absolute; content: ''; width: 100%; height: 1px; background-color: #DCDDE1; bottom: 0px; left: 0px; z-index: -1; } .sb-tabs-container .sb-tabs .tab { position: relative; padding: 9px 25px 15px 25px; display: inline-block; font-weight: 500; font-size: 16px; line-height: 160%; color: #8C8F9A; text-decoration: none; cursor: pointer; -webkit-transition: linear 0.2s; -ms-transition: linear 0.2s; transition: linear 0.2s; } .sb-tabs-container .sb-tabs .tab:not(:last-child) { margin-right: 20px; } .sb-tabs-container .sb-tabs .tab.active { color: #0068A0; } .sb-tabs-container .sb-tabs .tab-indicator { position: absolute; bottom: 0px; left: 0px; background-color: #0068A0; width: 200px; height: 2px; transition: all 0.3s cubic-bezier(0.22, 0.51, 0.53, 0.88); } .slide-fade-enter-active { transition: all 0.3s ease; position: absolute; } .slide-fade-leave-active { position: absolute; transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-enter, .slide-fade-leave-to { transform: translateX(10px); opacity: 0; } /*** 4.2 - Tab Boxes ***/ .sb-tab-content{ width: 100%; height: auto; } .sb-tab-content .sb-tab-box { background-color: #fff; padding: 24px; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); margin-bottom: 12px; } .sb-tab-content .sb-tab-box-small { padding: 13px 24px; } .sb-tab-content .sb-tab-box h3, #sbi-settings .sb-tab-content .sb-tab-box h3 { margin: 0px 0px 5px; font-size: 18px; line-height: 140%; color: #141B38; display: flex; } .sb-tab-content .sb-tab-box h3 .sb-tooltip-info { transform: translate(10px, 2px); cursor: pointer; } .sb-tab-content .sb-tab-box p { font-size: 14px; line-height: 160%; color: #8C8F9A; margin: 0px; } .sb-tab-content .sb-tab-box .tab-label { max-width: 270px; min-width: 270px; padding-right: 55px; box-sizing: border-box; float: left; position: relative; } .sb-tab-content .sb-tab-box .tab-label.tab-label-full { min-width: 100%; max-width: 100%; padding-right: 0; float: initial; } .sb-tab-content .sb-tab-box .tab-label .sb-help-text { font-size: 14px; line-height: 160%; color: #8C8F9A; } .sb-tab-content .license-status { font-size: 14px; line-height: 160%; color: #141B38; margin-bottom: 8px; display: inline-block; } .sbi-tab-field-inner-wrap .upgrade-info{ border-bottom: 1px solid #DCDDE1; margin-bottom: 24px; padding-bottom: 24px; } .dev-site-license-field .upgrade-info{ border-bottom: 0px solid #DCDDE1; padding-bottom: 0px; } .sb-tab-box.sb-license-box.license-type-free .license-status { font-style: italic; } .dev-site-license-field .sbi-upgrade-license-btn { text-decoration: none; transform: none !important; height: 38px; padding: 4px 13px; width: 165px; box-sizing: border-box; border: none; } .dev-site-license-field .sbi-upgrade-license-btn span { height: 20px; margin-right: 9px; } .sb-tab-content .sb-tab-box .sbi-tab-form-field{ width: calc(100% - 270px); float: left; flex-wrap: wrap; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .sbi-tab-field-inner-wrap { width: 100%; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .sbi-tab-field-inner-wrap:not(:last-child) { margin-bottom: 20px; } .sb-tab-box.sb-license-box.license-type-free .sbi-tab-form-field { flex-basis: 58%; flex-wrap: wrap; } .sb-tab-box.sb-manage-sources-box .sbi-tab-form-field { max-width: 1200px; } .sb-tab-box.sb-custom-css-box .sbi-tab-form-field, .sb-tab-box.sb-custom-js-box .sbi-tab-form-field { max-width: 840px; } @media (max-width: 1023px) { .sb-tab-content .sb-tab-box .tab-label { width: 100%; max-width: 100%; padding-right: 0; float: initial; margin-bottom: 20px; } .sb-tab-content .sb-tab-box .sbi-tab-form-field{ width: 100%; float: intial; } } .sb-tab-box.sb-license-box.license-type-free .sbi-tab-form-field .upgrade-info { width: 100%; border-bottom: 1px solid #DCDDE1; padding-bottom: 25px; margin-bottom: 25px; } .sb-tab-box.sb-license-box.license-type-free .field-left-content, .sb-tab-box.sb-license-box.license-type-free .field-right-content { order: 1; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .sbi-form-field { width: 100%; } .license-valid .sbi-form-field, .license-valid .sbi-form-field:focus { border-color: #59AB46; } .license-invalid .sbi-form-field { border-color: #D72C2C; } .sb-field-error .sbi-form-field, .sb-field-error .sbi-form-field:focus { border-color: #D72C2C; } .license-valid .field-icon { color: #59AB46; } .field-icon.field-icon-error { color: #D72C2C; } .license-valid .sb-form-field .field-icon, .sb-form-field .field-icon.field-icon-error { background: white; } .form-error .sbi-form-field, .license-expired .sbi-form-field { border-color: #ab4646; } .upgrade-info span { font-size: 14px; line-height: 22px; display: inline-block; } .upgrade-info span:last-child { font-style: italic; } .upgrade-info span a { font-weight: 700; color: #0068A0; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .sbi-btn{ transform: translate(10px, 0px); } .sb-tab-content .sb-tab-box.sb-caching-box .sbi-tab-form-field .sbi-btn, .sb-tab-content .sb-tab-box.sb-import-box .sbi-tab-form-field .sbi-btn{ transform: translate(0px); } .sb-tab-content .sb-tab-box.sb-license-box .sbi-tab-form-field .sb-form-field{ margin-bottom: 8px; } .license-valid .sbi-btn.loading svg path { fill: #141B38 } .sb-tab-content .sb-tab-box .sbi-tab-form-field .field-left-content { flex-basis: 73%; max-width: 465px; } .sb-tab-content .sb-tab-box.sb-license-box.license-type-free .sbi-tab-form-field .field-left-content { flex-basis: 73%; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .field-right-content { flex-basis: 20%; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .form-info { font-size: 12px; line-height: 22px; color: #27303F; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .form-info .manage-license a{ text-decoration-line: underline; color: #27303F; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .form-info .test-connection { color: #434960; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .form-info .upgrade a { color: #0068A0; font-weight: 600; margin-left: 8px; text-decoration: none; } .sb-tab-content .sb-tab-box.sb-reset-box-style { margin: 0; border-bottom: 1px solid #E8E8EB; } .sb-tooltip-content { position: absolute; background: #fff; border-radius: 2px; padding: 12px 26px 12px 16px; box-shadow: 1px 2px 4px 0px rgb(0 0 0 / 15%), -2px -1px 9px 0px rgb(0 0 0 / 13%); width: 497px; height: auto; max-height: 284px; bottom: 50px; box-sizing: border-box; right: -45px; z-index: 9999; } .sb-tooltip-content p { color: #141B38; font-size: 14px; line-height: 22px; font-weight: normal; } .sb-tooltip-content:after { width: 12px; height: 12px; content: ''; bottom: -7px; right: calc(50% - 6px); position: absolute; background: #fff; transform: rotate(45deg); box-shadow: 2px 2px 2px rgb(0 0 0 / 14%); } .sb-localization-box .sb-tooltip-content:after { right: calc(50% - 55px); } .sb-tooltip-content.sb-tooltip-bottom { bottom: inherit; top: 45px; box-shadow: -1px -2px 4px 0px rgb(0 0 0 / 15%), 2px 1px 9px 0px rgb(0 0 0 / 13%); } .sb-tooltip-content.sb-tooltip-bottom:after { bottom: inherit; top: -6px; box-shadow: -2px -2px 2px rgb(0 0 0 / 14%); } .sb-tab-content .sb-tab-box .sb-tooltip-content p { color: #141B38; } .sb-tab-content .sb-tab-box .sb-tooltip-content p:not(:last-child) { margin-bottom: 12px; } .sb-tab-content .sb-tab-box .sb-tooltip-content p a { color: #141B38; font-weight: 600; } .sb-gdpr-box .sb-gdpr-active { padding-left: 27px; position: relative; max-width: 560px; box-sizing: border-box; } .sb-gdpr-box .gdpr-help-text-yes { max-width: 560px; } .sb-gdpr-box .sb-gdpr-active .gdpr-active-icon { position: absolute; left: 0px; } .sb-gdpr-box .help-text a { font-weight: 400; } .sb-gdpr-box .sb-text-bold { font-weight: 700; cursor: pointer; } .sb-gdpr-box .sb-gdpr-bold { text-decoration: underline; } .sb-gdpr-info-tooltip { position: absolute; font-size: 14px; line-height: 22px; color: #141B38; background: #FFFFFF; border-radius: 2px; padding: 12px 26px 12px 16px; box-shadow: 1px 2px 4px 0px rgb(0 0 0 / 15%), -2px -1px 9px 0px rgb(0 0 0 / 13%); z-index: 99; width: 561px; bottom: -183px; box-sizing: border-box; } .sb-gdpr-info-tooltip:before { width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 10px solid #fff; content: ''; top: -10px; right: 260px; position: absolute; } .sb-gdpr-info-tooltip .sb-gdpr-info-headline { font-weight: 600; } .sb-gdpr-info-tooltip .sb-gdpr-info-list { margin: 0px; margin-top: 1px; padding-left: 20px; } .sb-gdpr-info-tooltip .sb-gdpr-info-list li { position: relative; margin-bottom: 2px; } .sb-gdpr-info-tooltip .sb-gdpr-info-list li:before { width: 3px; height: 3px; position: absolute; left: -12px; top: 10px; content: ''; background-color: #141B38; border-radius: 10px; } .recheck-license-status svg, .test-connection svg { width: 15px; height: 15px; transform: translate(2px, 3px); } .test-connection i { font-size: 14px; } .recheck-license-status.loading path, .test-connection.loading path { fill: #141B38 } .rrecheck-license-status.success svg, .test-connection.success svg { transform: translate(3px, 6px) } .test-connection i, .recheck-license-status i { font-size: 16px; transform: translate(-2px, 1px); } .recheck-license-status.success path, .test-connection.success path { fill: #59AB46; } .recheck-license-status.success i, .test-connection.success i { color: #59AB46; } .recheck-license-status.error i, .test-connection.error i { color: #D72C2C; } .recheck-license-status { margin-left: 8px; cursor: pointer; } .recheck-license-status i { margin-left: 8px; } .test-connection.error i { color: #D72C2C; } .test-connection a { color: #434960; font-weight: 600; margin-left: 4px; } .test-connection:not(.error):not(.success) { cursor: pointer; } .sbi-btn[disabled="disabled"] { cursor: not-allowed; color: #8C8F9A; background: #F3F4F5; } .sbi-btn[disabled="disabled"]:hover { color: #8C8F9A; } .sbi-btn[disabled="disabled"]:not(.import-btn) .icon path { fill: #8C8F9A; } .import-btn .icon svg:not(.checkmark) path { fill: #141B38; } .import-btn[disabled="disabled"] .icon svg:not(.checkmark) path { fill: #8C8F9A; } .sbi-btn .icon { margin-right: 12px; } .import-btn .icon.loading { transform: translate(-5px, 1px); } .import-btn .icon.success { transform: translate(-4px, 0px); } .import-btn .icon.error { transform: translate(-4px, 0px); } .import-btn .icon.error i { color: #D72C2C; } .import-btn .icon.success svg { stroke: #141B38 } .export-btn { text-decoration: none; } .export-btn:hover { color: inherit; } .sb-tab-box.sb-caching-box .sbi-caching-btn .loading path, .sb-tab-box.sb-optimize-box .optimize-image-btn .loading path, .sb-tab-box.sb-dpa-clear-box-style .loading path{ fill: rgba(23, 22, 22, .95) } .sb-tab-box.sb-caching-box .sbi-caching-btn .success svg, .sb-tab-box.sb-optimize-box .optimize-image-btn .success svg, .sb-tab-box.sb-dpa-clear-box-style .success svg{ stroke: rgba(23, 22, 22, .95) } /* Translation Tab */ .sb-tab-inner-card { margin-top: 30px; } .sbi-table { width: 100%; border: 1px solid #DCDDE1; padding: 0; border-spacing: 0; } .sbi-table thead th, .sbi-table tfoot th { background-color: #F3F4F5; font-size: 14px; line-height: 22px; color: #434960; padding: 10px 20px; font-weight: 400; text-align: left; box-sizing: border-box; border-bottom: 1px solid #DCDDE1; } .sbi-table tfoot th { border: 0; border-top: 1px solid #DCDDE1; } .sbi-table tbody td { padding: 6px 10px 6px 20px; box-sizing: border-box; } .sbi-table-row-header td { font-weight: 600; font-size: 16px !important; line-height: 26px; color: #141B38; box-sizing: border-box; padding: 10px 20px !important; } .sbi-table tbody td { background: #F3F4F5; font-size: 14px; } .sbi-table tbody:nth-child(2n) td { background-color:#fff; } .sbi-table tbody tr:not(.sbi-table-row-header):not(:last-child) td { border-bottom:1px solid #DCDDE1 } .sbi-table tbody tr:last-child td { padding: 6px 10px 6px 20px; } .sbi-table tbody tr td:first-child, .sbi-table tbody tr td:nth-child(2) { width: 25%; } .sbi-table tbody .sbi-input{ background: #FFFFFF; border: 1px solid #D0D1D7; box-sizing: border-box; border-radius: 1px; width: 100%; height: 38px; color: #2c3338; } .sbi-table tbody .sbi-input::placeholder { color: #8C8F9A; } .sbi-table tbody .sbi-input:focus { border: 1px solid #97989c; outline: none; box-shadow: none; } @media (max-width: 767px) { .sb-tabs-container .sb-tabs .tab { padding: 25px 10px; } .sbi-table th, .sbi-table td { display: block; width: 100%; } .sbi-table tbody tr td:first-child, .sbi-table tbody tr td:nth-child(2) { width: 100%; } .sbi-table tbody .sbi-input { height: 30px; min-height: 30px; font-size: 14px; } } .sb-feed-issue-box #sbi-send-report { width: 127px; min-width: 127px; height: 46px; padding: 6px 15px; } .sb-feed-issue-box #report-emails { width: 407px; height: 45px; padding: 8px 15px; font-size: 16px; line-height: 26px; } .sb-feed-issue-box #report-emails::placeholder { color: #8C8F9A; } .sb-feed-issue-box .feed-issues-fields { margin-bottom: 15px; display: flex; } .sb-feed-issue-box .feed-issues-fields * { margin: 0 10px 0 0; font-size: 16px; } .sb-tab-box.sb-optimize-box .sb-form-field, .sb-tab-box.sb-usage-box .sb-form-field, .sb-tab-box.sb-ajax-box .sb-form-field, .sb-tab-box.sb-show-credit-box .sb-form-field, .sb-tab-box.sb-admin-error-box .sb-form-field, .sb-tab-box.sb-fix-text-box .sb-form-field{ max-width: 695px; } .sb-tab-box.sb-feed-issue-box .sb-form-field .help-text { max-width: 670px; } /*To Be Checked*/ .sb-sources-list{ width: 100%; position: relative; display: grid; grid-template-columns: 48% 48%; grid-column-gap: 2%; } .sbi-fb-srcs-item-ins { display: flex; height: 62px; padding: 0 10px; position: relative; } .sb-srcs-item { box-sizing: border-box; position: relative; cursor: auto; display: block; height: 64px; border: 1px solid #E7E7E9; min-height: 60px; overflow: auto; margin-top: 15px; } .sb-srcs-item.expanded { height: auto; } .sb-source-error-wrap { display: flex; justify-content: center; align-items: center; margin-left: 9px; } .sb-source-error-wrap span { font-weight: 600; font-size: 12px; line-height: 160%; color: #D72C2C; margin-left: 5px; } .sb-source-error-wrap a { margin-left: 8px; font-weight: 600; font-size: 12px; line-height: 160%; text-decoration-line: underline; color: #0068A0; } .sb-srcs-new { display: flex; justify-content: center; align-items: center; font-size: 14px; color: #0068A0; background: #F9F9FA; font-weight: 400; transition: all 0.15s ease-in-out; border: 1px solid #E8E8EB; } .sb-srcs-new:hover { cursor: pointer; background: #E2F5FF; } .sb-srcs-new span.add-new-icon { margin-right: 11px; margin-top: 3px; } .sb-srcs-item-avatar{ display: flex; width: 42px; height: inherit; justify-content: center; align-items: center; margin-right: 10px; } .sb-srcs-item-avatar img{ width: 42px; height: 42px; border-radius: 50%; background: #eee; } .sb-srcs-item-inf{ width: 100%; height: inherit; display: flex; justify-content: center; flex-direction: column; } .sb-srcs-item-name{ font-weight: 600; color: #141B38; font-size: 16px; margin-bottom: 1px; padding-right: 60px; max-height: 32px; line-height: 1.1; padding-bottom: 2px; overflow: hidden; } .sb-account-has-error { border: 1px solid #f3c9c9; background: #fff8f8; } .sb-srcs-item-used{ color: #434960; display: flex; align-items: center; font-weight: 400; font-size: 12px; } .sbi-fb-srcs-info-item:first-of-type { align-items: center; } .sbi-fb-srcs-info-item { display: flex; border-top: 1px solid #E7E7E9; box-sizing: border-box; width: 100%; float: left; padding: 8px 10px; } .sbi-fb-srcs-info-item strong { font-size: 14px; width: 50px; } .sbi-fb-srcs-info-item span { font-size: 13px; line-height: 1.5em; color: #434960; font-weight: 400; display: inline-block; word-break: break-all; width: calc(100% - 80px); padding: 0 15px; box-sizing: border-box; } .sbi-fb-srcs-info-icon { width: 26px; height: 26px; display: flex; justify-content: center; align-items: center; cursor: pointer; margin-left: auto; border: 1px solid #D0D1D7; border-radius: 2px; transition: all 0.15s ease-in-out; } .sbi-fb-srcs-info-icon:hover { background: #F3F4F5; } .sbi-fb-srcs-info-icon:focus, .sbi-fb-srcs-info-icon:active { background: #E8E8EB; } .sbi-fb-srcs-info-icon svg { width: 15px; float: left; } .sb-control-src-expand-chevron { width: 7px; height: 7px; border-left: 2px solid currentColor; border-top: 2px solid currentColor; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sb-srcs-item-actions{ position: absolute; width: 70px; height: 31px; right: 7px; top: 7px; } .sb-srcs-item-actions-btn{ width: 30px; height: 31px; cursor: pointer; float: left; display: flex; justify-content: center; align-items: center; margin-left: 3px; } .sb-srcs-item-actions-btn svg{ float: left; width: 17px; fill: currentColor; } .sb-srcs-item-actions-btn.sb-srcs-item-angle-up svg { height: 10px; } .sb-srcs-item-cog, .sb-srcs-item-angle-up{ color: #434960; transition: all 0.15s ease-in-out; border-radius: 4px; } .sb-srcs-item-cog:hover, .sb-srcs-item-angle-up:hover { background: #F3F4F5; } .sb-srcs-item-cog:focus, .sb-srcs-item-cog:active, .sb-srcs-item-angle-up:focus, .sb-srcs-item-angle-up:active { background: #E8E8EB; } .sb-srcs-item-delete{ color: #D72C2C; transition: all 0.15s ease-in-out; border-radius: 4px; } .sb-srcs-item-delete:hover { background-color: #FCEDED; } .sb-srcs-item-delete:focus, .sb-srcs-item-delete:active { background: #eed4d4; } .sb-srcs-item-delete svg{ width: 13px; } #sbi-settings .sbi-fb-source-step1 .sbi-fb-source-top h3 { margin-bottom: 40px; } .sbi-fb-srcs-personal-btn{ height: 40px; width: 100%; float: left; display: flex; justify-content: center; align-items: center; background: #E2F5FF; cursor: pointer; color: #0068A0; font-weight: 600; } .sbi-fb-srcs-personal-btn svg{ float: left; margin-right: 10px; } /* Sources Instance Popup */ .sbi-fb-popup-feedinst .sbi-fb-source-top{ display: flex; align-items: center; } .sbi-fb-popup-feedinst h5{ margin-bottom: 0px; float: left; font-size: 27px; } .sbi-fb-fdinst-type{ padding: 5px 5px; background: #E8E8EB; margin-left: 12px; float: left; } .sbi-fb-inst-tbl-ctn{ padding: 0 23px 63px; } .sbi-fb-inst-tbl-ctn table{ width: 100%; border-spacing: unset; box-sizing: border-box; border: 1px solid #DCDDE1; text-align: left; } .sbi-fb-inst-tbl-ctn tfoot,.sbi-fb-inst-tbl-ctn thead{ background: #F3F4F5 } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf th, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf td{ font-size: 13px; color: #364152; padding: 13px 10px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr:nth-child(odd){ background: #fff; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr:nth-child(even){ background: #F3F4F5; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf tr th, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf tr td{ padding: 4px 20px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr td{ padding: 11px 20px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-name{ font-size: 14px; } .sbi-fb-inst-tbl-shrtc{ display: flex; align-items: center; } .sbi-fd-inst-btn{ width: 10px; height: 10px; box-sizing: border-box; border-right: 3px solid #8C8F9A; border-top: 3px solid #8C8F9A; cursor: pointer; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-fd-lst-actions .sbi-fd-lst-btn, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-btn { box-sizing: border-box; width: 36px; height: 32px; } .sbi-fd-lst-shortcode-cp { margin-left: 10px; } .sbi-fb-tltp-parent { position: relative; } .sbi-fd-lst-btn { width: 21px; height: 21px; display: inline-flex; justify-content: center; align-items: center; margin: 0 4px; cursor: pointer; color: #141B38; border-radius: 2px; border: 1px solid #D8DADD; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; background: #fff; } .sbi-fb-tltp-elem { position: absolute; color: #fff; background: #434960; font-size: 14px; padding: 7px 10px; border-radius: 3px; font-weight: 500; z-index: 9; text-align: center; opacity: 0; visibility: hidden; top: calc(-100% - 30px); left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-fb-tltp-elem span { position: relative; z-index: 3; } .sbi-fd-lst-btn svg { fill: currentColor; width: 14px; float: left; } .sbi-fd-lst-btn svg { height: 13px; } .sbi-fd-lst-thtf th{ border-bottom: 1px solid #DCDDE1; } .sbi-fd-lst-thtf td{ border-top: 1px solid #DCDDE1; } .sbi-fb-fdinst-type { padding: 5px 5px; background: #E8E8EB; margin-left: 12px; float: left; } .sbi-fd-lst-name { font-size: 17px; font-weight: 500; color: #0068A0!important; } .sbi-fb-inst-tbl-ctn a, .sbi-fb-inst-tbl-ctn a:focus { text-decoration: none; outline: none; } .sbi-fd-lst-actions .sbi-fd-lst-btn, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-btn { box-sizing: border-box; width: 36px; height: 32px; background: transparent; } .sbi-fd-lst-btn svg { fill: currentColor; width: 14px; float: left; } .sbi-fb-tltp-parent:hover .sbi-fb-tltp-elem { top: calc(-100% - 20px); opacity: 1; visibility: visible; } .sbi-fb-tltp-elem:after { content: ''; position: absolute; height: 10px; width: 10px; bottom: -5px; left: calc(50% - 5px); background: #434960; transform: rotate( -45deg ); } /*** 6.0 Sticky Widget ***/ .sbi-stck-wdg{ position: fixed; right: 21px; z-index: 9; bottom: 20px; } .sbi-stck-wdg-btn{ width: 52px; height: 52px; background: #fff; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; filter: drop-shadow(0px 9px 13px rgba(0, 0, 0, 0.2)); } .sbi-stck-wdg-btn svg{ width: 25px; fill: #FE544F; height: 33px; float: left; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls, .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls svg{ display: block; } .sbi-stck-wdg-btn-cls{ width: inherit; height: inherit; position: relative; color: #364152; box-shadow: 0px 1px 6px rgb(0 0 0 / 5%), 0px 9px 12px rgb(0 0 0 / 5%); border-radius: 70px; } .sbi-stck-wdg-btn-cls svg { width: 14px; height: 14px; position: absolute; top: 50%; right: 0; bottom: 0; left: 50%; margin-top: -7px; margin-left: -7px; } .sbi-stck-pop{ position: absolute; width: 292px; height: auto; background: #fff; border: 1px solid #E2E8F0; box-sizing: border-box; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 3px 14px rgba(0, 0, 0, 0.12); border-radius: 2px; padding: 20px; right: 0px; bottom: 66px; color: #141B38; padding-bottom: 82px; } .sbi-stck-wdg[data-active="true"] .sbi-stck-pop{ bottom: 66px; opacity: 1; visibility: visible; } .sbi-stck-pop svg{ fill: currentColor; } .sbi-stck-el-list{ border: 1px solid #DCDDE1; border-radius: 2px; } .sbi-stck-el{ display: flex; align-items: center; padding: 11px 13px; border-bottom: 1px solid #DCDDE1; transition: background .15s ease-in-out; } .sbi-stck-el:hover{ background: #F3F4F5; } .sbi-stck-el:last-of-type{ border-bottom: 0px; } .sbi-stck-el-list .sbi-chevron svg{ width: 5px; height: 8px; } .sbi-fs-a { width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0; z-index: 1; } .sbi-stck-el .sbi-stck-el-txt{ color: #27303F; } .sbi-stck-el.sbi-stck-el-upgrd{ padding: 8px 14px; font-size: 14px; background: var(--cl-orange); color: #fff; position: relative; transition: background .15s ease-in-out; } .sbi-chevron { position: absolute; right: 14px } .sbi-stck-el.sbi-stck-el-upgrd .sbi-stck-el-txt{ color: #fff; } .sbi-stck-el.sbi-stck-el-upgrd:after{ top: 20px; opacity: 1; } .sbi-stck-el-icon{ margin-right: 10px; } .sbi-stck-el-icon svg{ width: 17px; float: left; } .sbi-stck-title{ margin-top: 20px; margin-bottom: 10px; color: #141B38; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-stck-follow{ background: #F3F4F5; margin-top: 20px; left: 0px; bottom: 0px; position: absolute; padding: 12px 20px; display: flex; align-items: center; } .sbi-stck-follow span{ font-weight: 600; font-size: 14px; } .sbi-stck-flw-links{ display: flex; justify-content: center; align-items: center; margin-left: auto; } .sbi-stck-flw-links a{ width: 36px; height: 28px; color: inherit; display: inline-flex; justify-content: center; align-items: center; margin-left: 4px; border-radius: 2px; transition: background .15s ease-in-out; } .sbi-stck-flw-links svg{ width: 17px; color: #141B38; } .sbi-stck-flw-links a:hover{ background: #fff; } .sbi-stck-flw-links a:hover svg{ color: inherit; } .sb-tab-content .sb-tab-box.sb-reset-box-style .sbi-tab-form-field .sbi-btn, .sb-tab-content .sb-tab-box.sb-dpa-clear-box-style .sbi-tab-form-field .sbi-btn { transform: none; margin-bottom: 15px; } /*** 7.0 Responsive ***/ @media (max-width: 1429px) { .caching-form-fields-group { display: inline-block; } .caching-form-fields-group select { margin-bottom: 5px; } } @media (min-width: 1429px) { .caching-form-fields-group { display: flex; } } @media (max-width: 1023px) { .sb-tab-content .sb-tab-box .tab-label { width: 100%; max-width: 100%; padding-right: 0; float: initial; margin-bottom: 20px; } .sb-tab-content .sb-tab-box .sbi-tab-form-field{ width: 100%; float: intial; } } @media (max-width: 1320px) { .sb-feed-issue-box .feed-issues-fields { display: inline-block; } .sb-feed-issue-box .feed-issues-fields * { margin-bottom: 5px; } } @media (max-width: 767px) { .auto-fold #wpcontent { padding-left: 0; } .sbi-fb-full-wrapper { padding: 70px 20px 0 20px; } .sbi-fb-hd-btn { padding: 0px 15px 0px 7px; } .sbi-fb-header { padding: 0px 20px; } .sb-notification-ctn { left: 20px; } .sb-tab-box.sb-export-box .sb-form-field .d-flex{ flex-wrap: wrap; } .sb-form-field .sbi-select { width: 100%; } .sb-tab-content .sb-tab-box .sbi-tab-form-field { flex-wrap: wrap; } .sb-license-box .sbi-tab-form-field .sbi-btn { transform: translate(0px, 0px) !important; margin-top: 10px; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .field-left-content { flex-basis: 100%; } .sb-export-box .sbi-tab-form-field .sbi-btn { transform: translate(0px, 0px) !important; margin-top: 10px; } .sb-feed-issue-box .feed-issues-fields { width: 100%; } .sb-feed-issue-box #report-emails { max-width: 100%; } .sbi-table thead th, .sbi-table tfoot th { display: none; } .sbi-table tbody tr:not(.sbi-table-row-header) td:last-child { margin-bottom: 20px; } .sbi-table tbody { background-color: #f3f4f5; } .sbi-table tbody:nth-child(2n) { background-color: #fff; } .sb-tab-content .sb-tab-box .sbi-tab-form-field .d-flex{ flex-wrap: wrap; } .sb-sources-list { grid-template-columns: 100%; } .sb-tabs-container .sb-tabs { flex-direction: column-reverse; flex-wrap: wrap; align-items: flex-end; } .sbi-fb-full-wrapper { padding: 82px 20px 0 20px; } .sb-tabs-container .sb-tabs .left-buttons { width: 100%; display: flex; } .sb-tabs-container .sb-tabs .right-buttons { transform: translateY(-15px); } .sb-tabs-container .sb-tabs .left-buttons .tab { flex-grow: 1; flex-basis: 0; padding: 15px 10px; text-align: center; } .sb-tabs-container { margin-top: -45px; } #wpbody-content { padding-bottom: 50px; } .sb-form-field .sbi-select.size-md { width: 100%; max-width: 100%; } } @media (max-width: 567px) { .sb-tabs-container .sb-tabs .tab:not(:last-child) { margin-right: 10px; } } @media (max-width: 420px) { .sb-tabs-container .sb-tabs .left-buttons .tab { padding: 15px 7px; font-size: 14px; } } .sb-button-standard{ position: relative; font-style: normal; font-weight: 600; font-size: 14px; padding: 10px 20px 10px 39px; line-height: 16px; height: auto; } .sb-button-standard svg { width: 16px; height: 16px; position: absolute; left: 13px; right: auto; top: 10px; bottom: auto; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } .sb-tab-content .sb-tab-box.sbi-uo-install-notice { background: #FFF7E5; box-shadow: 0px 9px 16px rgba(0, 0, 0, 0.0196802), 0px 3.75998px 6.68442px rgba(0, 0, 0, 0.0282725), 0px 2.01027px 3.57381px rgba(0, 0, 0, 0.035), 0px 1.12694px 2.00345px rgba(0, 0, 0, 0.0417275), 0px 0.598509px 1.06402px rgba(0, 0, 0, 0.0503198), 0px 0.249053px 0.442761px rgba(0, 0, 0, 0.07); border-radius: 8px; padding: 12px 12px 12px 34px; } .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice { display: flex; justify-content: space-between; align-items: center; gap: 20px; } .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice .sbi-notice-left, .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice .sbi-notice-right { display: flex; gap: 20px; align-items: center; } .sb-tab-content .sbi-uo-install-notice .sbi-notice-text p { font-weight: 600; font-size: 16px; line-height: 160%; color: #663D00; } .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice .sbi-notice-right .sbi-notice-learn-more { background: #F9F9FA; border: 1px solid #E6E6EB; box-shadow: 0px 2px 5px rgba(60, 66, 87, 0.05), 0px 1px 1px rgba(0, 0, 0, 0.05), inset 0px -1px 1px rgba(0, 0, 0, 0.12); border-radius: 4px; padding: 7px 11px; transition: all .2s ease-in; } .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice .sbi-notice-right .sbi-notice-learn-more:hover { background-color: #ededed; } .sb-tab-content .sbi-uo-install-notice .sbi-tab-notice .sbi-notice-right .sbi-uo-notice-dismiss { border: none; background-color: transparent; padding: 0px; }admin/assets/css/admin-notifications.css000064400000030461150515074560014413 0ustar00#sbi-notifications { position: relative; background: #FFFFFF 0 0 no-repeat padding-box; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; opacity: 1; min-height: 48px; padding: 20px 120px 20px 82px; margin: 0 0 14px 0; } #sbi-notifications * { box-sizing: border-box; } #sbi-notifications .bell, #sbi-notifications .thumb{ position: absolute; top: 20px; left: 24px; width: 34px; height: 44px; } #sbi-notifications .thumb img { max-width: 100%; } #sbi-notifications .thumb .img-overlay { top: 42px; left: -6px; width: 54px; position: absolute; background: #ca4a1f; color: #fff; padding: 2px 4px; border-radius: 3px; line-height: 1; font-size: 11px; font-weight: bold; text-align: center; } #sbi-notifications .messages .message { display: none; } #sbi-notifications .messages .message.current { display: block; } #sbi-notifications .messages .message .title { font-weight: 600; font-size: 18px; line-height: 25px; margin: 0; color: #141B38; letter-spacing: 0; } #sbi-notifications .messages .message .content { font-weight: normal; font-size: 14px; line-height: 22px; margin: 6px 0 32px 0; color: #434960; } #sbi-notifications .messages .message .buttons { margin: -15px 105px 3px 0; display: flex; } .sbi-btn { transition: all 0.15s ease-in-out; letter-spacing: 0.2px; } /*orange*/ .sbi-btn-orange{ background: #FE544F!important; color: #fff!important; } .sbi-btn-orange:hover{ background: #EC352F!important; color: #fff!important; } .sbi-btn-orange:focus, .sbi-btn-orange:active{ background: #BC120E!important; color: #fff!important; } /*grey*/ .sbi-btn-grey{ background: #F3F4F5!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sbi-btn-grey:hover{ background: #fff!important; color: #141B38!important; border: 1px solid #DCDDE1!important; } .sbi-btn-grey:focus, .sbi-btn-grey:active{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } #sbi-notifications .messages .message .buttons a { font-weight: 600; padding: 6px 12px; border-radius: 2px; box-sizing: border-box; height: 32px; text-decoration: none; font-size: 12px; } #sbi-notifications .messages .message .buttons a.sbi-btn-orange { border: 1px solid #FE544F } #sbi-notifications .messages .message .buttons a:not(:last-child) { margin-right: 8px; } #sbi-notifications .messages .message .buttons a:focus, #sbi-notifications .messages .message .buttons a:active { outline: none; box-shadow: none; } #sbi-notifications .dismiss { position: absolute; top: 14px; right: 14px; width: 16px; height: 16px; color: #72777C; font-size: 16px; cursor: pointer; text-align: center; vertical-align: middle; line-height: 16px; } #sbi-notifications .dismiss svg { width: 15px; height: 15px; } #sbi-notifications .dismiss svg path { fill: #8C8F9A; } #sbi-notifications .navigation { position: absolute; bottom: 24px; right: 21px; width: 72px; height: 30px; } #sbi-notifications .navigation a { display: block; width: 32px; height: 32px; border: 1px solid #DCDDE1; border-radius: 2px; font-size: 8px; text-align: center; vertical-align: middle; line-height: 30px; cursor: pointer; background: #F3F4F5; color: #141B38; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease-in-out; } #sbi-notifications .navigation svg { width: 9px; height: 9px; } #sbi-notifications .navigation a:not(.disabled):hover { background-color: #fff; } #sbi-notifications .navigation a:not(.disabled):focus, #sbi-notifications .navigation a:not(.disabled):active { background: #E8E8EB; color: #141B38; } #sbi-notifications .navigation .prev { float: left; } #sbi-notifications .navigation .next { float: right; } #sbi-notifications .navigation .disabled { background: #E8E8EB; color: #8C8F9A; cursor: default; } @media screen and (max-width: 768px) { #sbi-notifications { padding: 15px 15px 15px 72px; } #sbi-notifications .messages .message .title { margin: 0 30px 0 0; } #sbi-notifications .messages .message .content { font-size: 16px; line-height: 24px; } #sbi-notifications .messages .message .buttons { margin: -30px 80px 0 0; } #sbi-notifications .messages .message .buttons a { margin: 0; display: table; } #sbi-notifications .messages .message .buttons .button-secondary { margin-top: 6px; } } /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2Nzcy9hZG1pbi1ub3RpZmljYXRpb25zLmNzcyIsInNvdXJjZXMiOlsiYXNzZXRzL3Njc3MvYWRtaW4tbm90aWZpY2F0aW9ucy5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEFkbWluIG5vdGlmaWNhdGlvbiBzdHlsZXMuXG5cbiN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXG5cdHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0YmFja2dyb3VuZDogI0ZGRkZGRiAwIDAgbm8tcmVwZWF0IHBhZGRpbmctYm94O1xuXHRib3gtc2hhZG93OiAwcHggNXB4IDE1cHggIzAwMDAwMDBEO1xuXHRib3JkZXItcmFkaXVzOiA2cHg7XG5cdG9wYWNpdHk6IDE7XG5cdG1pbi1oZWlnaHQ6IDQ4cHg7XG5cdHBhZGRpbmc6IDE1cHggMTAycHggMTVweCA3MnB4O1xuXHRtYXJnaW46IDAgMCAxNHB4IDA7XG5cblx0KiB7XG5cdFx0Ym94LXNpemluZzogYm9yZGVyLWJveDtcblx0fVxuXG5cdC5iZWxsIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdGxlZnQ6IDE1cHg7XG5cdFx0d2lkdGg6IDQycHg7XG5cdFx0aGVpZ2h0OiA0OHB4O1xuXHR9XG5cblx0Lm1lc3NhZ2VzIHtcblx0XHQubWVzc2FnZSB7XG5cdFx0XHRkaXNwbGF5OiBub25lO1xuXG5cdFx0XHQmLmN1cnJlbnQge1xuXHRcdFx0XHRkaXNwbGF5OiBibG9jaztcblx0XHRcdH1cblxuXHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IGJvbGQ7XG5cdFx0XHRcdGZvbnQtc2l6ZTogMTdweDtcblx0XHRcdFx0bGluZS1oZWlnaHQ6IDIwcHg7XG5cdFx0XHRcdG1hcmdpbjogMDtcblx0XHRcdFx0Y29sb3I6ICM0NDQ7XG5cdFx0XHR9XG5cblx0XHRcdC5jb250ZW50IHtcblx0XHRcdFx0Zm9udC13ZWlnaHQ6IG5vcm1hbDtcblx0XHRcdFx0Zm9udC1zaXplOiAxM3B4O1xuXHRcdFx0XHRsaW5lLWhlaWdodDogMjBweDtcblx0XHRcdFx0bWFyZ2luOiA2cHggMCA0MHB4IDA7XG5cdFx0XHR9XG5cblx0XHRcdC5idXR0b25zIHtcblx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRhIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgNnB4IDAgMDtcblx0XHRcdFx0XHRwYWRkaW5nOiA4cHggMTBweDtcblx0XHRcdFx0XHRsaW5lLWhlaWdodDogMTNweDtcblx0XHRcdFx0XHRmb250LXNpemU6IDEzcHg7XG5cdFx0XHRcdFx0bWluLWhlaWdodDogdW5zZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9uLXNlY29uZGFyeSB7XG5cdFx0XHRcdFx0Ym9yZGVyOiAxcHggc29saWQgIzAwNzFBMTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC5kaXNtaXNzIHtcblx0XHRwb3NpdGlvbjogYWJzb2x1dGU7XG5cdFx0dG9wOiAxNXB4O1xuXHRcdHJpZ2h0OiAxNXB4O1xuXHRcdHdpZHRoOiAxNnB4O1xuXHRcdGhlaWdodDogMTZweDtcblx0XHRjb2xvcjogIzcyNzc3Qztcblx0XHRmb250LXNpemU6IDE2cHg7XG5cdFx0Y3Vyc29yOiBwb2ludGVyO1xuXHRcdHRleHQtYWxpZ246IGNlbnRlcjtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdGxpbmUtaGVpZ2h0OiAxNnB4O1xuXG5cdFx0Jjpob3ZlciB7XG5cdFx0XHRjb2xvcjogI2RjMzIzMjtcblx0XHR9XG5cdH1cblxuXHQubmF2aWdhdGlvbiB7XG5cdFx0cG9zaXRpb246IGFic29sdXRlO1xuXHRcdGJvdHRvbTogMTVweDtcblx0XHRyaWdodDogMTVweDtcblx0XHR3aWR0aDogNjNweDtcblx0XHRoZWlnaHQ6IDMwcHg7XG5cblx0XHRhIHtcblx0XHRcdGRpc3BsYXk6IGJsb2NrO1xuXHRcdFx0d2lkdGg6IDMwcHg7XG5cdFx0XHRoZWlnaHQ6IDMwcHg7XG5cdFx0XHRib3JkZXI6IDFweCBzb2xpZCAjN0U4OTkzO1xuXHRcdFx0Ym9yZGVyLXJhZGl1czogM3B4O1xuXHRcdFx0Zm9udC1zaXplOiA4cHg7XG5cdFx0XHR0ZXh0LWFsaWduOiBjZW50ZXI7XG5cdFx0XHR2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuXHRcdFx0bGluZS1oZWlnaHQ6IDMwcHg7XG5cdFx0XHRjdXJzb3I6IHBvaW50ZXI7XG5cdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0Y29sb3I6ICM0MTQ1NEE7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWYxO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC5wcmV2IHtcblx0XHRcdGZsb2F0OiBsZWZ0O1xuXHRcdH1cblxuXHRcdC5uZXh0IHtcblx0XHRcdGZsb2F0OiByaWdodDtcblx0XHR9XG5cblx0XHQuZGlzYWJsZWQge1xuXHRcdFx0Ym9yZGVyLWNvbG9yOiAjZGRkZGRkO1xuXHRcdFx0Y29sb3I6ICNBMEE1QUE7XG5cdFx0XHRjdXJzb3I6IGRlZmF1bHQ7XG5cblx0XHRcdCY6aG92ZXIge1xuXHRcdFx0XHRiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3NjhweCkge1xuXG5cdCN3cGZvcm1zLW5vdGlmaWNhdGlvbnMge1xuXHRcdHBhZGRpbmc6IDE1cHggMTVweCAxNXB4IDcycHg7XG5cblx0XHQubWVzc2FnZXMge1xuXG5cdFx0XHQubWVzc2FnZSB7XG5cblx0XHRcdFx0LnRpdGxlIHtcblx0XHRcdFx0XHRtYXJnaW46IDAgMzBweCAwIDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuY29udGVudCB7XG5cdFx0XHRcdFx0Zm9udC1zaXplOiAxNnB4O1xuXHRcdFx0XHRcdGxpbmUtaGVpZ2h0OiAyNHB4XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQuYnV0dG9ucyB7XG5cdFx0XHRcdFx0bWFyZ2luOiAtMzBweCA4MHB4IDAgMDtcblxuXHRcdFx0XHRcdGEge1xuXHRcdFx0XHRcdFx0bWFyZ2luOiAwO1xuXHRcdFx0XHRcdFx0ZGlzcGxheTogdGFibGU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0LmJ1dHRvbi1zZWNvbmRhcnkge1xuXHRcdFx0XHRcdFx0bWFyZ2luLXRvcDogNnB4O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxBQUFBLHNCQUFzQixDQUFDO0VBRXRCLFFBQVEsRUFBRSxRQUFRO0VBQ2xCLFVBQVUsRUFBRSxpQ0FBaUM7RUFDN0MsVUFBVSxFQUFFLHNCQUFzQjtFQUNsQyxhQUFhLEVBQUUsR0FBRztFQUNsQixPQUFPLEVBQUUsQ0FBQztFQUNWLFVBQVUsRUFBRSxJQUFJO0VBQ2hCLE9BQU8sRUFBRSxvQkFBb0I7RUFDN0IsTUFBTSxFQUFFLFVBQVU7Q0FxSGxCOztBQTlIRCxBQVdDLHNCQVhxQixDQVdyQixDQUFDLENBQUM7RUFDRCxVQUFVLEVBQUUsVUFBVTtDQUN0Qjs7QUFiRixBQWVDLHNCQWZxQixDQWVyQixLQUFLLENBQUM7RUFDTCxRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULElBQUksRUFBRSxJQUFJO0VBQ1YsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtDQUNaOztBQXJCRixBQXdCRSxzQkF4Qm9CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQUFDO0VBQ1IsT0FBTyxFQUFFLElBQUk7Q0FvQ2I7O0FBN0RILEFBMkJHLHNCQTNCbUIsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLEFBR04sUUFBUSxDQUFDO0VBQ1QsT0FBTyxFQUFFLEtBQUs7Q0FDZDs7QUE3QkosQUErQkcsc0JBL0JtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FPUCxNQUFNLENBQUM7RUFDTixXQUFXLEVBQUUsSUFBSTtFQUNqQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxDQUFDO0VBQ1QsS0FBSyxFQUFFLElBQUk7Q0FDWDs7QUFyQ0osQUF1Q0csc0JBdkNtQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FlUCxRQUFRLENBQUM7RUFDUixXQUFXLEVBQUUsTUFBTTtFQUNuQixTQUFTLEVBQUUsSUFBSTtFQUNmLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLE1BQU0sRUFBRSxZQUFZO0NBQ3BCOztBQTVDSixBQThDRyxzQkE5Q21CLENBdUJyQixTQUFTLENBQ1IsUUFBUSxDQXNCUCxRQUFRLENBQUM7RUFDUixNQUFNLEVBQUUsY0FBYztDQWF0Qjs7QUE1REosQUFpREksc0JBakRrQixDQXVCckIsU0FBUyxDQUNSLFFBQVEsQ0FzQlAsUUFBUSxDQUdQLENBQUMsQ0FBQztFQUNELE1BQU0sRUFBRSxTQUFTO0VBQ2pCLE9BQU8sRUFBRSxRQUFRO0VBQ2pCLFdBQVcsRUFBRSxJQUFJO0VBQ2pCLFNBQVMsRUFBRSxJQUFJO0VBQ2YsVUFBVSxFQUFFLEtBQUs7Q0FDakI7O0FBdkRMLEFBeURJLHNCQXpEa0IsQ0F1QnJCLFNBQVMsQ0FDUixRQUFRLENBc0JQLFFBQVEsQ0FXUCxpQkFBaUIsQ0FBQztFQUNqQixNQUFNLEVBQUUsaUJBQWlCO0NBQ3pCOztBQTNETCxBQWdFQyxzQkFoRXFCLENBZ0VyQixRQUFRLENBQUM7RUFDUixRQUFRLEVBQUUsUUFBUTtFQUNsQixHQUFHLEVBQUUsSUFBSTtFQUNULEtBQUssRUFBRSxJQUFJO0VBQ1gsS0FBSyxFQUFFLElBQUk7RUFDWCxNQUFNLEVBQUUsSUFBSTtFQUNaLEtBQUssRUFBRSxPQUFPO0VBQ2QsU0FBUyxFQUFFLElBQUk7RUFDZixNQUFNLEVBQUUsT0FBTztFQUNmLFVBQVUsRUFBRSxNQUFNO0VBQ2xCLGNBQWMsRUFBRSxNQUFNO0VBQ3RCLFdBQVcsRUFBRSxJQUFJO0NBS2pCOztBQWhGRixBQTZFRSxzQkE3RW9CLENBZ0VyQixRQUFRLEFBYU4sTUFBTSxDQUFDO0VBQ1AsS0FBSyxFQUFFLE9BQU87Q0FDZDs7QUEvRUgsQUFrRkMsc0JBbEZxQixDQWtGckIsV0FBVyxDQUFDO0VBQ1gsUUFBUSxFQUFFLFFBQVE7RUFDbEIsTUFBTSxFQUFFLElBQUk7RUFDWixLQUFLLEVBQUUsSUFBSTtFQUNYLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7Q0FzQ1o7O0FBN0hGLEFBeUZFLHNCQXpGb0IsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLENBQUM7RUFDRCxPQUFPLEVBQUUsS0FBSztFQUNkLEtBQUssRUFBRSxJQUFJO0VBQ1gsTUFBTSxFQUFFLElBQUk7RUFDWixNQUFNLEVBQUUsaUJBQWlCO0VBQ3pCLGFBQWEsRUFBRSxHQUFHO0VBQ2xCLFNBQVMsRUFBRSxHQUFHO0VBQ2QsVUFBVSxFQUFFLE1BQU07RUFDbEIsY0FBYyxFQUFFLE1BQU07RUFDdEIsV0FBVyxFQUFFLElBQUk7RUFDakIsTUFBTSxFQUFFLE9BQU87RUFDZixnQkFBZ0IsRUFBRSxPQUFPO0VBQ3pCLEtBQUssRUFBRSxPQUFPO0NBS2Q7O0FBMUdILEFBdUdHLHNCQXZHbUIsQ0FrRnJCLFdBQVcsQ0FPVixDQUFDLEFBY0MsTUFBTSxDQUFDO0VBQ1AsZ0JBQWdCLEVBQUUsT0FBTztDQUN6Qjs7QUF6R0osQUE0R0Usc0JBNUdvQixDQWtGckIsV0FBVyxDQTBCVixLQUFLLENBQUM7RUFDTCxLQUFLLEVBQUUsSUFBSTtDQUNYOztBQTlHSCxBQWdIRSxzQkFoSG9CLENBa0ZyQixXQUFXLENBOEJWLEtBQUssQ0FBQztFQUNMLEtBQUssRUFBRSxLQUFLO0NBQ1o7O0FBbEhILEFBb0hFLHNCQXBIb0IsQ0FrRnJCLFdBQVcsQ0FrQ1YsU0FBUyxDQUFDO0VBQ1QsWUFBWSxFQUFFLE9BQU87RUFDckIsS0FBSyxFQUFFLE9BQU87RUFDZCxNQUFNLEVBQUUsT0FBTztDQUtmOztBQTVISCxBQXlIRyxzQkF6SG1CLENBa0ZyQixXQUFXLENBa0NWLFNBQVMsQUFLUCxNQUFNLENBQUM7RUFDUCxnQkFBZ0IsRUFBRSxPQUFPO0NBQ3pCOztBQUtKLE1BQU0sQ0FBQyxNQUFNLE1BQU0sU0FBUyxFQUFFLEtBQUs7RUFFbEMsQUFBQSxzQkFBc0IsQ0FBQztJQUN0QixPQUFPLEVBQUUsbUJBQW1CO0dBNkI1QjtFQTlCRCxBQU9HLHNCQVBtQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQUVQLE1BQU0sQ0FBQztJQUNOLE1BQU0sRUFBRSxVQUFVO0dBQ2xCO0VBVEosQUFXRyxzQkFYbUIsQ0FHckIsU0FBUyxDQUVSLFFBQVEsQ0FNUCxRQUFRLENBQUM7SUFDUixTQUFTLEVBQUUsSUFBSTtJQUNmLFdBQVcsRUFBRSxJQUNkO0dBQUM7RUFkSixBQWdCRyxzQkFoQm1CLENBR3JCLFNBQVMsQ0FFUixRQUFRLENBV1AsUUFBUSxDQUFDO0lBQ1IsTUFBTSxFQUFFLGNBQWM7R0FVdEI7RUEzQkosQUFtQkksc0JBbkJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FHUCxDQUFDLENBQUM7SUFDRCxNQUFNLEVBQUUsQ0FBQztJQUNULE9BQU8sRUFBRSxLQUFLO0dBQ2Q7RUF0QkwsQUF3Qkksc0JBeEJrQixDQUdyQixTQUFTLENBRVIsUUFBUSxDQVdQLFFBQVEsQ0FRUCxpQkFBaUIsQ0FBQztJQUNqQixVQUFVLEVBQUUsR0FBRztHQUNmIn0= */ admin/assets/css/about.css000064400000042074150515074560011571 0ustar00/* * About Us CSS TABLE OF CONTENTS * * 1.0 - GLOBAL * 2.0 - HEADER * 3.0 - 3.0 - ABOUT US CONTAINER * 3.1 - SECTION HEADER * 3.2 - ABOUT TEAM BOX * 3.3 - PLUGINS BOX * 4.0 - STICKY WIDGET * 5.0 - RESPONSIVENESS */ /*** 1.0 - GLOBAL ***/ .clearfix { display: inline-block; } /* start commented backslash hack \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } #sbi-about { -webkit-font-smoothing: antialiased; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; } #wpcontent { padding-left: 0px; } #wpbody-content { padding-bottom: 40px; } .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } /*orange*/ .sb-btn-orange{ background: #FE544F!important; color: #fff!important; } .sb-btn-orange:hover{ background: #EC352F!important; color: #fff!important; } .sb-btn-orange:focus, .sb-btn-orange:active{ background: #BC120E!important; color: #fff!important; } .sbi-fb-full-wrapper{ padding: 0 53px; padding-top: 82px; } .sbi-fb-fs { width: 100%; position: relative; float: left; box-sizing: border-box; } /*** 2.0 - HEADER ***/ .sbi-fb-create-ctn{ margin-top: 90px; } .sbi-fb-header{ height: 64px; position: absolute; display: flex; flex-direction: row; justify-content: space-between; align-items: center; background: #fff; padding: 0px 52px; z-index: 2; } .sbi-fb-header-left { display: flex; } .sbi-fb-header-left .sb-social-wall-link-wrap { margin-left: 30px; } .sb-social-wall-link-wrap { display: flex; font-size: 14px; margin: 10px 0 10px 30px; } .sb-social-wall-link:first-child { padding-left: 0; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link { padding: 0 12px; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link a { text-decoration: none; } .sb-social-wall-link a:focus { outline: none; box-shadow: none; } .sb-social-wall-link:last-child { border-right: none; } .sbi-fb-hd-logo{ display: flex; vertical-align: middle; align-items: center; gap: 5px; } .sbi-fb-hd-logo .sb-logo-letters-wrap { margin-bottom: 4px; } .sbi-fb-hd-logo .breadcrumb-title{ font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: 0em; margin-left: 4px; } .sbi-fb-hd-logo .separator{ margin: 0 5px 0 10px; } .sbi-fb-hd-btn{ height: 38px; cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 0px 15px 0px 16px; font-weight: 600; font-size:14px; color: #353A41; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; position: relative; text-decoration: none; transition: all 0.15s ease-in-out; } .sbi-fb-hd-btn:focus { outline: none; box-shadow: none; } .sbi-fb-hd-btn:hover { color: inherit; background-color: #fff; } .sbi-fb-hd-btn i{ margin: 0px 5px; } .sbi-fb-hd-btn[data-icon="left"]{ padding-right: 20px!important; } .sbi-fb-full-wrapper .section-header h1 { font-size: 32px; line-height: 40px; } /*** 3.0 - SB CONTAINER ***/ .sbi-sb-container { max-width: 875px; position: relative; margin: auto; margin-top: 33px; box-sizing: border-box; } /*** 3.1 - SECTION HEADER ***/ .sbi-section-header h2 { font-weight: 600; font-size: 32px; line-height: 40px; color: #141B38; margin: 0 0 5px 0; } .sbi-section-header p { font-size: 13px; line-height: 18px; color: #8C8F9A; margin: 0; } .sbi-section-second-header { margin-top: 36px; } .sbi-section-second-header h3 { font-weight: 600; font-size: 24px; line-height: 29px; color: #141B38; margin: 0 0 5px 0; } .sbi-section-second-header p { font-size: 14px; line-height: 22px; color: #8C8F9A; margin-top: 0px; } .sbi-oembed-plugin-box { background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); margin-bottom: 10px; padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; } .sb-action-buttons .sbi-btn { display: flex; align-items: center; vertical-align: middle; justify-content: center; background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; padding: 6px 19px; font-weight: 600; font-size: 12px; line-height: 18px; color: #141B38; box-sizing: border-box; letter-spacing: 0.2px; cursor: pointer; text-decoration: none; transition: all 0.15s ease-in-out; } .sb-action-buttons .sbi-btn:hover { background: #FFFFFF; border: 1px solid #D0D1D7; } .sb-action-buttons .sbi-btn:focus, .sb-action-buttons .sbi-btn:active { background: #E8E8EB; border: 1px solid #D0D1D7; box-shadow: none; outline: none; } .sb-action-buttons .sbi-btn.loading svg { height: 13px; transform: translate(0px, 2px); } .sb-action-buttons .sbi-btn.sb-btn-add svg { margin-right: 10px; height: 10px; } .sb-action-buttons .sbi-btn.sb-btn-add path { fill: #141B38; } .sb-action-buttons .sbi-btn.sb-btn-installed { background: #E8E8EB; color: #8C8F9A; cursor: not-allowed } .sb-action-buttons .sbi-btn.sb-btn-add { min-width: 110px; } .sb-action-buttons .sbi-btn.sb-btn-activate { background-color: #0068A0; border-color: #0068A0; color: #fff; } .sb-action-buttons .sbi-btn.sb-btn-activate:hover { background-color: #0096CC; border-color: #0096CC; } .sb-action-buttons .sbi-btn.sb-btn-activate:focus, .sb-action-buttons .sbi-btn.sb-btn-activate:active { background-color: #004D77; border-color: #004D77; } .sb-action-buttons .sbi-btn.sb-btn-deactivate { background-color: #D72C2C; border-color: #D72C2C; color: #fff; display: none; } .sb-action-buttons .sbi-btn.sb-btn-deactivate:hover { background-color: #DF5757; border-color: #DF5757; } .sb-action-buttons .sbi-btn.sb-btn-deactivate:focus, .sb-action-buttons .sbi-btn.sb-btn-deactivate:active { background-color: #841919; border-color: #841919; } .sb-action-buttons .sbi-btn:not(:last-child) { margin-right: 8px; } .sb-btn-add-plugin svg { height: 10px; margin-right: 10px; } .sb-btn-add-plugin svg path { fill: #141B38; } .sb-btn-installed svg { margin-right: 10px; } /*** 3.2 - ABOUT TEAM BOX ***/ .sbi-about-box { margin-top: 11px; } .sbi-about-box .sb-team-avatar { padding: 55px 0 50px; background-image: linear-gradient(to right, #0068A0 , #0096CC); text-align: center; } .sbi-about-box .sb-team-avatar img { max-width: 100%; width: 603px; } .sbi-about-box .sb-team-info { display: flex; padding: 48px; background: #fff; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); border-radius: 0 0 2px 2px; text-align: left; } .sb-team-info > div { min-width: 50%; } .sbi-about-box .sb-team-info .sb-team-left h2 { font-size: 24px; line-height: 29px; letter-spacing: 0; color: #141B38; margin: 0; padding-right: 5px; } .sbi-about-box .sb-team-info .sb-team-right { padding-left: 37px; max-width: 365px; box-sizing: border-box; } .sbi-about-box .sb-team-info .sb-team-right p { font-size: 14px; line-height: 22px; color: #64748B; margin-top: 0; } /*** 3.3 - EXTENSION PLUGINS BOX CONTAINER ***/ .sbi-plugins-boxes-container { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 20px; gap: 12px; } .sbi-plugins-boxes-container.sb-recommended-plugins { margin-top: 26px; } .sbi-plugins-boxes-container .sb-plugins-box{ background-color: #fff; padding: 20px 16px; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); border-radius: 4px; display: flex; width: calc((100% / 2) - 6px); box-sizing: border-box; } .sbi-plugins-boxes-container .sb-plugins-box .icon { max-width: 80px; padding-right: 5px; box-sizing: border-box; width: 80px; min-width: 72px; } .sbi-plugins-boxes-container.sb-recommended-plugins .sb-plugins-box .icon { max-width: 80px; padding-right: 23px; box-sizing: border-box; width: 80px; min-width: 72px; padding-left: 8px; } .sbi-plugins-boxes-container .sb-plugins-box .icon img { max-width: 100%; } .sb-plugins-box .sb-box-title { font-weight: 600; font-size: 16px; line-height: 22px; color: #141B38; margin-top: 0; margin-bottom: 5px; } .sb-plugins-box .sb-box-description { margin: 0; font-size: 13px; line-height: 18px; color: #8C8F9A; } .sb-recommended-plugins .sb-plugins-box .sb-box-description { min-height: 69px; } .sb-plugins-box .sb-action-buttons { margin-top: 20px; display: flex; } .sbi-plugins-boxes-container .sb-plugins-box.sbi-social-wall-plugin-box { padding: 27px 20px 35px 120px; flex-basis: 100%; margin-right: 0; justify-content: center; position: relative; overflow: hidden; } .sbi-social-wall-plugin-box .sb-action-buttons .sb-btn-add { padding: 6px 4px 6px 15px; } .sbi-social-wall-plugin-box .sb-action-buttons .sb-btn-add span { margin-left: 12px; } .sbi-plugins-boxes-container .sb-plugins-box.sbi-social-wall-plugin-box .plugin-box-content { z-index: 11; } .sbi-social-wall-plugin-box .sb-box-title { font-size: 24px; line-height: 27px; letter-spacing: 0; color: #141B38; } .sbi-social-wall-plugin-box .sb-box-description { font-size: 14px; line-height: 22px; color: #8C8F9A; } .sbi-social-wall-plugin-box .sb-box-bg-image { position: absolute; z-index: 0; left: -40px; width: 356px; top: 0; } .sbi-social-wall-plugin-box .sb-box-bg-image img { max-width: 100%; } /*** 4.0 Sticky Widget ***/ .sbi-stck-wdg{ position: fixed; right: 21px; z-index: 9; bottom: 20px; } .sbi-stck-wdg-btn{ width: 52px; height: 52px; background: #fff; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; filter: drop-shadow(0px 9px 13px rgba(0, 0, 0, 0.2)); } .sbi-stck-wdg-btn svg{ width: 25px; fill: #FE544F; height: 33px; float: left; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls, .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls svg{ display: block; } .sbi-stck-wdg-btn-cls{ width: inherit; height: inherit; position: relative; color: #364152; box-shadow: 0px 1px 6px rgb(0 0 0 / 5%), 0px 9px 12px rgb(0 0 0 / 5%); border-radius: 70px; } .sbi-stck-wdg-btn-cls svg { width: 14px; height: 14px; position: absolute; top: 50%; right: 0; bottom: 0; left: 50%; margin-top: -7px; margin-left: -7px; } .sbi-stck-pop{ position: absolute; width: 292px; height: auto; background: #fff; border: 1px solid #E2E8F0; box-sizing: border-box; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 3px 14px rgba(0, 0, 0, 0.12); border-radius: 2px; padding: 20px; right: 0px; bottom: 66px; color: #141B38; padding-bottom: 82px; } .sbi-stck-wdg[data-active="true"] .sbi-stck-pop{ bottom: 66px; opacity: 1; visibility: visible; } .sbi-stck-pop svg{ fill: currentColor; } .sbi-stck-el-list{ border: 1px solid #DCDDE1; border-radius: 2px; } .sbi-stck-el{ display: flex; align-items: center; padding: 11px 13px; border-bottom: 1px solid #DCDDE1; transition: background .15s ease-in-out; font-size: 12px; } .sbi-stck-el:hover{ background: #F3F4F5; } .sbi-stck-el:last-of-type{ border-bottom: 0px; } .sbi-stck-el-list .sbi-chevron svg{ width: 5px; height: 8px; } .sbi-fs-a { width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0; z-index: 1; } .sbi-stck-el .sbi-stck-el-txt{ color: #27303F; } .sbi-stck-el.sbi-stck-el-upgrd{ padding: 9px 14px; font-size: 14px; background: var(--cl-orange); color: #fff; position: relative; transition: background .15s ease-in-out; font-weight: 600; } .sbi-chevron { position: absolute; right: 14px } .sbi-stck-el.sbi-stck-el-upgrd .sbi-stck-el-txt{ color: #fff; } .sbi-stck-el.sbi-stck-el-upgrd:after{ top: 20px; opacity: 1; } .sbi-stck-el-icon{ margin-right: 10px; } .sbi-stck-el-icon svg{ width: 17px; float: left; } .sbi-stck-title{ margin-top: 20px; margin-bottom: 10px; color: #141B38; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-stck-follow{ background: #F3F4F5; margin-top: 20px; left: 0px; bottom: 0px; position: absolute; padding: 12px 20px; display: flex; align-items: center; } .sbi-stck-follow span{ font-weight: 600; font-size: 14px; } .sbi-stck-flw-links{ display: flex; justify-content: center; align-items: center; margin-left: auto; } .sbi-stck-flw-links a{ width: 36px; height: 28px; color: inherit; display: inline-flex; justify-content: center; align-items: center; margin-left: 4px; border-radius: 2px; transition: background .15s ease-in-out; } .sbi-stck-flw-links svg{ width: 17px; color: #141B38; } .sbi-stck-flw-links a:hover{ background: #fff; } .sbi-stck-flw-links a:hover svg{ color: inherit; } /*** 5.0 - RESPONSIVENESS ***/ @media (max-width: 1024px) { .sbi-extensions-boxes-container .sb-extensions-box{ width: calc(48% - 33px); } .sbi-extensions-boxes-container .sb-extensions-box:not(:nth-child(3n)) { margin-right: 0; } .sbi-extensions-boxes-container .sb-extensions-box:not(:nth-child(2n)) { margin-right: 12px; } .sbi-plugins-boxes-container { padding-right: 0px; } .sbi-social-wall-plugin-box .sb-box-bg-image { left: -45px; } .sbi-plugins-boxes-container .sb-plugins-box.sbi-social-wall-plugin-box { padding: 27px 20px 22px 130px; } .sbi-section-second-header { padding-right: 15px; } } @media (min-width: 768px) and (max-width: 1024px) { .sbi-social-wall-plugin-box .sb-box-bg-image { left: -85px; } .sb-action-buttons .sbi-btn { padding: 6px 15px; } .sb-recommended-plugins .sb-plugins-box { min-height: 209px; } .sb-recommended-plugins .sb-plugins-box .sb-box-description { min-height: 90px; } } @media (max-width: 767px) { .auto-fold #wpcontent { padding-left: 0; } .sbi-fb-full-wrapper { padding: 70px 20px 0 20px; } .sbi-fb-hd-btn { padding: 0px 15px 0px 7px; } .sbi-fb-header { padding: 0px 20px; } .sbi-about-box .sb-team-info { padding: 30px; } .sbi-plugins-boxes-container .sb-plugins-box { width: 100%; } .sbi-plugins-boxes-container .sb-plugins-box.sbi-social-wall-plugin-box { display: flex; flex-direction: column; padding: 0px; } .sbi-social-wall-plugin-box .sb-box-bg-image { position: initial; background-color: #c3d7f3; width: 100%; height: 190px; } .sbi-plugins-boxes-container .sb-plugins-box.sbi-social-wall-plugin-box .plugin-box-content { padding: 18px 24px 24px; } .sbi-social-wall-plugin-box .sb-box-title { font-size: 18px; } .sbi-social-wall-plugin-box .sb-box-bg-image img { max-width: 401px; } .sbi-about-box .sb-team-info { flex-direction: column; } .sbi-about-box .sb-team-info .sb-team-right { padding-left: 0; max-width: none; margin-top: 30px; } .sb-recommended-plugins .sb-plugins-box .sb-box-description { min-height: initial; } .sbi-about-box .sb-team-avatar { display: none; } .sbi-about-box .sb-team-info .sb-team-left h2 { font-size: 21px; } } @media (max-width: 570px) { .sbi-extensions-boxes-container .sb-extensions-box { width: calc(100% - 30px); } .sbi-plugins-boxes-container { padding-right: 0px; } .sbi-plugins-boxes-container .sb-plugins-box:not(:nth-child(2n)) { margin-right: 0px; } } @media (max-width: 480px) { .sbi-fb-hd-btn { padding: 0px 10px 0px 7px !important; } .sbi-fb-hd-btn[data-icon="left"] { padding-right: 10px!important; } .sbi-plugins-boxes-container .sb-plugins-box .icon { width: 60px; min-width: 60px; } .sbi-plugins-boxes-container.sb-recommended-plugins .sb-plugins-box .icon { padding-right: 11px; width: 58px; min-width: 58px; padding-left: 8px; } } .sb-button-standard{ position: relative; font-style: normal; font-weight: 600; font-size: 14px; padding: 10px 20px 10px 39px; line-height: 16px; height: auto; } .sb-button-standard svg { width: 16px; height: 16px; position: absolute; left: 13px; right: auto; top: 10px; bottom: auto; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } admin/assets/js/support.js000064400000010356150515074560011641 0ustar00var support_data = { genericText: sbi_support.genericText, articles: sbi_support.articles, links: sbi_support.links, system_info: sbi_support.system_info, system_info_n: sbi_support.system_info_n, exportFeed: 'none', stickyWidget: false, feeds: sbi_support.feeds, supportUrl: sbi_support.supportUrl, socialWallActivated: sbi_support.socialWallActivated, socialWallLinks: sbi_support.socialWallLinks, siteSearchUrl: sbi_support.siteSearchUrl, siteSearchUrlWithArgs: null, searchKeywords: null, buttons: sbi_support.buttons, links: sbi_support.links, supportPageUrl: sbi_support.supportPageUrl, systemInfoBtnStatus: 'collapsed', copyBtnStatus: null, ajax_handler: sbi_support.ajax_handler, nonce: sbi_support.nonce, icons: sbi_support.icons, images: sbi_support.images, svgIcons : sbi_support.svgIcons, notificationElement : { type : 'success', // success, error, warning, message text : '', shown : null } } var sbisupport = new Vue({ el: "#sbi-support", http: { emulateJSON: true, emulateHTTP: true }, data: support_data, methods: { copySystemInfo: function() { let self = this; const el = document.createElement('textarea'); el.className = 'sbi-fb-cp-clpboard'; el.value = self.system_info_n; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el); this.notificationElement = { type : 'success', text : this.genericText.copiedToClipboard, shown : "shown" }; setTimeout(function() { this.notificationElement.shown = "hidden"; }.bind(self), 3000); }, expandSystemInfo: function() { this.systemInfoBtnStatus = ( this.systemInfoBtnStatus == 'collapsed' ) ? 'expanded' : 'collapsed'; }, expandBtnText: function() { if ( this.systemInfoBtnStatus == 'collapsed' ) { return this.buttons.expand; } else if ( this.systemInfoBtnStatus == 'expanded' ) { return this.buttons.collapse; } }, exportFeedSettings: function() { // return if no feed is selected if ( this.exportFeed === 'none' ) { return; } let url = this.ajax_handler + '?action=sbi_export_settings_json&nonce=' + this.nonce + '&feed_id=' + this.exportFeed; window.location = url; }, searchDoc: function() { let self = this; let searchInput = document.getElementById('sbi-search-doc-input'); searchInput.addEventListener('keyup', function ( event ) { let url = new URL( self.siteSearchUrl ); let search_params = url.searchParams; if ( self.searchKeywords ) { search_params.set('search', self.searchKeywords); } search_params.set('plugin', 'instagram'); url.search = search_params.toString(); self.siteSearchUrlWithArgs = url.toString(); if ( event.key === 'Enter' ) { window.open( self.siteSearchUrlWithArgs, '_blank'); } }) }, searchDocStrings: function() { let self = this; let url = new URL( this.siteSearchUrl ); let search_params = url.searchParams; setTimeout(function() { search_params.set('search', self.searchKeywords); search_params.set('plugin', 'instagram'); url.search = search_params.toString(); self.siteSearchUrlWithArgs = url.toString(); }, 10); }, goToSearchDocumentation: function() { if ( this.searchKeywords !== null && this.siteSearchUrlWithArgs !== null ) { window.open( this.siteSearchUrlWithArgs, '_blank'); } }, /** * Toggle Sticky Widget view * * @since 4.0 */ toggleStickyWidget: function() { this.stickyWidget = !this.stickyWidget; }, }, }) admin/assets/js/oembeds.js000064400000015446150515074560011550 0ustar00var sbioembeds_data = { nonce: sbi_oembeds.nonce, genericText: sbi_oembeds.genericText, images: sbi_oembeds.images, modal: sbi_oembeds.modal, links: sbi_oembeds.links, supportPageUrl: sbi_oembeds.supportPageUrl, socialWallActivated: sbi_oembeds.socialWallActivated, socialWallLinks: sbi_oembeds.socialWallLinks, stickyWidget: false, facebook: sbi_oembeds.facebook, instagram: sbi_oembeds.instagram, connectionURL: sbi_oembeds.connectionURL, isFacebookActivated: sbi_oembeds.facebook.active, facebookInstallBtnText: null, fboEmbedLoader: false, instaoEmbedLoader: false, openFacebookInstaller: false, loaderSVG: sbi_oembeds.loaderSVG, checkmarkSVG: sbi_oembeds.checkmarkSVG, timesCircleSVG: sbi_oembeds.timesCircleSVG, installerStatus: null } var sbioEmbeds = new Vue({ el: "#sbi-oembeds", http: { emulateJSON: true, emulateHTTP: true }, data: sbioembeds_data, methods: { openFacebookllModal: function() { this.openFacebookInstaller = true }, closeModal: function() { this.openFacebookInstaller = false }, isoEmbedsEnabled: function() { if ( this.facebook.doingOembeds && this.instagram.doingOembeds ) { return true; } return; }, FacebookShouldInstallOrEnable: function() { // if the plugin is activated and installed then just enable oEmbed if( this.isFacebookActivated ) { this.enableFacebookOembed(); return; } // if the plugin is not activated and installed then open the modal to install and activate the plugin if( !this.isFacebookActivated ) { this.openFacebookllModal(); return; } }, installFacebook: function() { this.installerStatus = 'loading'; let data = new FormData(); data.append( 'action', sbi_oembeds.facebook.installer.action ); data.append( 'nonce', sbi_oembeds.nonce ); data.append( 'plugin', sbi_oembeds.facebook.installer.plugin ); data.append( 'type', 'plugin' ); fetch(sbi_oembeds.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == false ) { this.installerStatus = 'error' } if( data.success == true ) { this.isFacebookActivated = true; this.installerStatus = 'success' } if ( typeof data.data === 'object') { this.facebookInstallBtnText = data.data.msg; } else { this.facebookInstallBtnText = data.data; } setTimeout(function() { this.installerStatus = null; }.bind(this), 3000); return; }); }, enableFboEmbed: function() { this.fboEmbedLoader = true; window.location = this.connectionURL; return; }, enableFacebookOembed: function() { this.facebookoEmbedLoader = true; window.location = this.connectionURL; return; }, disableFboEmbed: function() { this.fboEmbedLoader = true; let data = new FormData(); data.append( 'action', 'disable_facebook_oembed_from_instagram' ); data.append( 'nonce', this.nonce ); fetch(sbi_oembeds.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { this.fboEmbedLoader = false; this.facebook.doingOembeds = false; // get the updated connection URL after disabling oEmbed this.connectionURL = data.data.connectionUrl; } return; }); }, disableInstaoEmbed: function() { this.instaoEmbedLoader = true; let data = new FormData(); data.append( 'action', 'disable_instagram_oembed_from_instagram' ); data.append( 'nonce', this.nonce ); fetch(sbi_oembeds.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { this.instaoEmbedLoader = false; this.instagram.doingOembeds = false; // get the updated connection URL after disabling oEmbed this.connectionURL = data.data.connectionUrl; } return; }); }, installButtonText: function( buttonText = null ) { if ( buttonText ) { return buttonText; } else if ( this.facebook.installer.nextStep == 'free_install' ) { return this.modal.install; } else if ( this.facebook.installer.nextStep == 'free_activate' ) { return this.modal.activate; } }, installIcon: function() { if ( this.isFacebookActivated ) { return; } if( this.installerStatus == null ) { return this.modal.plusIcon; } else if( this.installerStatus == 'loading' ) { return this.loaderSVG; } else if( this.installerStatus == 'success' ) { return this.checkmarkSVG; } else if( this.installerStatus == 'error' ) { return this.timesCircleSVG; } }, /** * Toggle Sticky Widget view * * @since 4.0 */ toggleStickyWidget: function() { this.stickyWidget = !this.stickyWidget; }, }, created() { // Display the "Install" button text on modal depending on condition if ( this.facebook.installer.nextStep == 'free_install' ) { this.facebookInstallBtnText = this.modal.install; } else if ( this.facebook.installer.nextStep == 'free_activate' || this.facebook.installer.nextStep == 'pro_activate' ) { this.facebookInstallBtnText = this.modal.activate; } } })admin/assets/js/settings.js000064400000125354150515074560011772 0ustar00var sbiSettings; // Declaring as global variable for quick prototyping var settings_data = { adminUrl: sbi_settings.admin_url, nonce: sbi_settings.nonce, ajaxHandler: sbi_settings.ajax_handler, model: sbi_settings.model, feeds: sbi_settings.feeds, links: sbi_settings.links, tooltipName: null, sourcesList: sbi_settings.sources, dialogBoxPopupScreen: sbi_settings.dialogBoxPopupScreen, selectSourceScreen: sbi_settings.selectSourceScreen, uncannyAutomatorScreen : sbi_settings.uncannyAutomatorScreen, automatorInstallBtnStatus: 'normal', enableAutomatorSetupStep : sbi_settings.uncannyAutomatorScreen.enableSetupStep, uoActive : sbi_settings.uoActive, disableAutomatorBtn : false, socialWallActivated: sbi_settings.socialWallActivated, socialWallLinks: sbi_settings.socialWallLinks, stickyWidget: false, exportFeed: 'none', locales: sbi_settings.locales, timezones: sbi_settings.timezones, genericText: sbi_settings.genericText, generalTab: sbi_settings.generalTab, feedsTab: sbi_settings.feedsTab, translationTab: sbi_settings.translationTab, advancedTab: sbi_settings.advancedTab, footerUpgradeUrl: sbi_settings.footerUpgradeUrl, upgradeUrl: sbi_settings.upgradeUrl, supportPageUrl: sbi_settings.supportPageUrl, isDevSite: sbi_settings.isDevSite, licenseKey: sbi_settings.licenseKey, pluginItemName: sbi_settings.pluginItemName, licenseType: 'free', licenseStatus: sbi_settings.licenseStatus, licenseErrorMsg: sbi_settings.licenseErrorMsg, extensionsLicense: sbi_settings.extensionsLicense, extensionsLicenseKey: sbi_settings.extensionsLicenseKey, extensionFieldHasError: false, cronNextCheck: sbi_settings.nextCheck, currentView: null, selected: null, current: 0, sections: ["General", "Feeds", "Advanced"], indicator_width: 0, indicator_pos: 0, forwards: true, currentTab: null, import_file: null, gdprInfoTooltip: null, loaderSVG: sbi_settings.loaderSVG, timesCircleSVG: sbi_settings.timesCircleSVG, checkmarkSVG: sbi_settings.checkmarkSVG, uploadSVG: sbi_settings.uploadSVG, exportSVG: sbi_settings.exportSVG, reloadSVG: sbi_settings.reloadSVG, checkmarCircleSVG: sbi_settings.checkmarCircleSVG, tooltipHelpSvg: sbi_settings.tooltipHelpSvg, tooltip: { text: '', hover: false }, cogSVG: sbi_settings.cogSVG, deleteSVG: sbi_settings.deleteSVG, svgIcons: sbi_settings.svgIcons, testConnectionStatus: null, recheckLicenseStatus: null, btnStatus: null, uploadStatus: null, clearCacheStatus: null, optimizeCacheStatus: null, clearErrorLogStatus: null, dpaResetStatus: null, pressedBtnName: null, loading: false, hasError: sbi_settings.hasError, dialogBox: { active: false, type: null, heading: null, description: null, customButtons: undefined }, sourceToDelete: {}, viewsActive: { sourcePopup: false, sourcePopupScreen: 'redirect_1', sourcePopupType: 'creation', instanceSourceActive: null, automatorIntegrationModal : false, }, //Add New Source newSourceData: sbi_settings.newSourceData ? sbi_settings.newSourceData : null, sourceConnectionURLs: sbi_settings.sourceConnectionURLs, returnedApiSourcesList: [], manualSourcePopupInit: sbi_settings.manualSourcePopupInit, addNewSource: { typeSelected: 'page', manualSourceID: null, manualSourceToken: null }, selectedFeed: 'none', expandedFeedID: null, notificationElement: { type: 'success', // success, error, warning, message text: '', shown: null }, selectedSourcesToConnect: [], //Loading Bar fullScreenLoader: false, appLoaded: false, previewLoaded: false, loadingBar: true, notificationElement: { type: 'success', // success, error, warning, message text: '', shown: null } }; // The tab component Vue.component("tab", { props: ["section", "index"], template: ` {{section}} `, created: () => { let urlParams = new URLSearchParams(window.location.search); let view = urlParams.get('view'); if (view === null) { view = 'general'; } settings_data.currentView = view; settings_data.currentTab = settings_data.sections[0]; settings_data.selected = "app-1"; }, methods: { emitWidth: function (el) { settings_data.indicator_width = jQuery(el).outerWidth(); settings_data.indicator_pos = jQuery(el).position().left; }, changeComponent: function (index) { var prev = settings_data.current; if (prev < index) { settings_data.forwards = false; } else if (prev > index) { settings_data.forwards = true; } settings_data.selected = "app-" + (index + 1); settings_data.current = index; }, activeTab: function (section) { this.setView(section.toLowerCase().trim()); settings_data.currentTab = section; }, setView: function (section) { history.replaceState({}, null, settings_data.adminUrl + 'admin.php?page=sbi-settings&view=' + section); } } }); var sbiSettings = new Vue({ el: "#sbi-settings", http: { emulateJSON: true, emulateHTTP: true }, data: settings_data, created: function () { this.$nextTick(function () { let tabEl = document.querySelector('.tab'); settings_data.indicator_width = tabEl.offsetWidth; }); setTimeout(function () { settings_data.appLoaded = true; }, 350); }, mounted: function () { var self = this; // set the current view page on page load let activeEl = document.querySelector('a.tab#' + settings_data.currentView); // we have to uppercase the first letter let currentView = settings_data.currentView.charAt(0).toUpperCase() + settings_data.currentView.slice(1); let viewIndex = settings_data.sections.indexOf(currentView) + 1; settings_data.indicator_width = activeEl.offsetWidth; settings_data.indicator_pos = activeEl.offsetLeft; settings_data.selected = "app-" + viewIndex; settings_data.current = viewIndex; settings_data.currentTab = currentView; setTimeout(function () { settings_data.appLoaded = true; }, 350); }, computed: { getStyle: function () { return { position: "absolute", bottom: "0px", left: settings_data.indicator_pos + "px", width: settings_data.indicator_width + "px", height: "2px" }; }, chooseDirection: function () { if (settings_data.forwards == true) { return "slide-fade"; } else { return "slide-fade"; } } }, methods: { activateLicense: function () { if (this.licenseType === 'free') { this.runOneClickUpgrade(); } else { this.activateProLicense(); } }, activateProLicense: function () { this.hasError = false; this.loading = true; this.pressedBtnName = 'sbi'; let data = new FormData(); data.append('action', 'sbi_activate_license'); data.append('license_key', this.licenseKey); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.licenseStatus = 'inactive'; this.hasError = true; this.loading = false; return; } if (data.success == true) { let licenseData = data.data.licenseData; this.licenseStatus = data.data.licenseStatus; this.loading = false; this.pressedBtnName = null; if ( data.data.licenseStatus == 'inactive' || data.data.licenseStatus == 'invalid' || data.data.licenseStatus == 'expired' ) { this.hasError = true; if (licenseData.error) { this.licenseErrorMsg = licenseData.errorMsg } } } return; }); }, deactivateLicense: function () { this.loading = true; this.pressedBtnName = 'sbi'; let data = new FormData(); data.append('action', 'sbi_deactivate_license'); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == true) { this.licenseStatus = data.data.licenseStatus; this.loading = false; this.pressedBtnName = null; } return; }); }, runOneClickUpgrade: function () { this.hasError = false; this.loading = true; this.pressedBtnName = 'sbi'; let data = new FormData(); data.append('action', 'sbi_maybe_upgrade_redirect'); data.append('license_key', this.licenseKey); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success === false) { this.licenseStatus = 'invalid'; this.hasError = true; this.loading = false; if (typeof data.data !== 'undefined') { this.licenseErrorMsg = data.data.message } return; } if (data.success === true) { window.location.href = data.data.url } return; }); }, licenseActiveAction: function (extension) { extension = typeof extension !== 'undefined' ? extension : false; if (this.licenseType === 'free') { this.runOneClickUpgrade(); } else { if (typeof extension !== 'undefined') { this.deactivateExtensionLicense(extension); } else { this.deactivateLicense(); } } }, /** * Activate Extensions License * * @since 4.0 * * @param {object} extension */ activateExtensionLicense: function (extension) { let licenseKey = this.extensionsLicenseKey[extension.name]; this.extensionFieldHasError = false; this.loading = true; this.pressedBtnName = extension.name; if (!licenseKey) { this.loading = false; this.extensionFieldHasError = true; return; } let data = new FormData(); data.append('action', 'sbi_activate_extension_license'); data.append('license_key', licenseKey); data.append('extension_name', extension.name); data.append('extension_item_name', extension.itemName); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { this.loading = false; if (data.success == true) { this.extensionFieldHasError = false; this.pressedBtnName = null; if (data.data.licenseStatus == 'invalid') { this.extensionFieldHasError = true; this.notificationElement = { type: 'error', text: this.genericText.invalidLicenseKey, shown: "shown" }; } if (data.data.licenseStatus == 'valid') { this.notificationElement = { type: 'success', text: this.genericText.licenseActivated, shown: "shown" }; } extension.licenseStatus = data.data.licenseStatus; extension.licenseKey = licenseKey; setTimeout(function () { this.notificationElement.shown = "hidden"; }.bind(this), 3000); } return; }); }, /** * Deactivate Extensions License * * @since 4.0 * * @param {object} extension */ deactivateExtensionLicense: function (extension) { let licenseKey = this.extensionsLicenseKey[extension.name]; this.extensionFieldHasError = false; this.loading = true; this.pressedBtnName = extension.name; let data = new FormData(); data.append('action', 'sbi_deactivate_extension_license'); data.append('extension_name', extension.name); data.append('extension_item_name', extension.itemName); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { this.loading = false; if (data.success == true) { this.extensionFieldHasError = false; this.pressedBtnName = null; if (data.data.licenseStatus == 'deactivated') { this.notificationElement = { type: 'success', text: this.genericText.licenseDeactivated, shown: "shown" }; } extension.licenseStatus = data.data.licenseStatus; extension.licenseKey = licenseKey; setTimeout(function () { this.notificationElement.shown = "hidden"; }.bind(this), 3000); } return; }); }, testConnection: function () { this.testConnectionStatus = 'loading'; let data = new FormData(); data.append('action', 'sbi_test_connection'); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.testConnectionStatus = 'error'; this.testConnectionStatusMessage = data.data.error; } if (data.success == true) { this.testConnectionStatus = 'success'; setTimeout(function () { this.testConnectionStatus = null; }.bind(this), 3000); } return; }); }, recheckLicense: function (licenseKey, itemName, optionName = null) { this.recheckLicenseStatus = 'loading'; this.pressedBtnName = optionName; let data = new FormData(); data.append('action', 'sbi_recheck_connection'); data.append('license_key', licenseKey); data.append('item_name', itemName); data.append('option_name', optionName); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == true) { if (data.data.license == 'valid') { this.recheckLicenseStatus = 'success'; } if (data.data.license == 'expired') { this.recheckLicenseStatus = 'error'; } // if the api license status has changed from old stored license status // then reload the page to show proper error message and notices // or hide error messages and notices if (data.data.licenseChanged == true) { location.reload(); } setTimeout(function () { this.pressedBtnName = null; this.recheckLicenseStatus = null; }.bind(this), 3000); } return; }); }, recheckLicenseIcon: function () { if (this.recheckLicenseStatus == null) { return this.generalTab.licenseBox.recheckLicense; } else if (this.recheckLicenseStatus == 'loading') { return this.loaderSVG; } else if (this.recheckLicenseStatus == 'success') { return this.timesCircleSVG + ' ' + this.generalTab.licenseBox.licenseValid; } else if (this.recheckLicenseStatus == 'error') { return this.timesCircleSVG + ' ' + this.generalTab.licenseBox.licenseExpired; } }, recheckBtnText: function (btnName) { if (this.recheckLicenseStatus == null || this.pressedBtnName != btnName) { return this.generalTab.licenseBox.recheckLicense; } else if (this.recheckLicenseStatus == 'loading' && this.pressedBtnName == btnName) { return this.loaderSVG; } else if (this.recheckLicenseStatus == 'success') { return this.timesCircleSVG + ' ' + this.generalTab.licenseBox.licenseValid; } else if (this.recheckLicenseStatus == 'error') { return this.timesCircleSVG + ' ' + this.generalTab.licenseBox.licenseExpired; } }, testConnectionIcon: function () { if (this.testConnectionStatus == 'loading') { return this.loaderSVG; } else if (this.testConnectionStatus == 'success') { return this.timesCircleSVG + ' ' + this.generalTab.licenseBox.connectionSuccessful; } else if (this.testConnectionStatus == 'error') { return this.timesCircleSVG + ' ' + ` ${this.generalTab.licenseBox.connectionFailed} ${this.testConnectionStatusMessage}`; } }, importFile: function () { document.getElementById("import_file").click(); }, uploadFile: function (event) { this.uploadStatus = 'loading'; let file = this.$refs.file.files[0]; let data = new FormData(); data.append('action', 'sbi_import_settings_json'); data.append('file', file); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { this.uploadStatus = null; this.$refs.file.files[0] = null; if (data.success == false) { this.notificationElement = { type: 'error', text: this.genericText.failedToImportFeed, shown: "shown" }; } if (data.success == true) { this.feeds = data.data.feeds; this.notificationElement = { type: 'success', text: this.genericText.feedImported, shown: "shown" }; } setTimeout(function () { this.notificationElement.shown = "hidden"; }.bind(this), 3000); }); }, exportFeedSettings: function () { // return if no feed is selected if (this.exportFeed === 'none') { return; } let url = this.ajaxHandler + '?action=sbi_export_settings_json&nonce=' + this.nonce + '&feed_id=' + this.exportFeed; window.location = url; }, saveSettings: function () { this.btnStatus = 'loading'; this.pressedBtnName = 'saveChanges'; let data = new FormData(); data.append('action', 'sbi_save_settings'); data.append('model', JSON.stringify(this.model)); data.append('sbi_license_key', this.licenseKey); data.append('extensions_license_key', JSON.stringify(this.extensionsLicenseKey)); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.btnStatus = 'error'; return; } this.cronNextCheck = data.data.cronNextCheck; this.btnStatus = 'success'; setTimeout(function () { this.btnStatus = null; this.pressedBtnName = null; }.bind(this), 3000); }); }, clearCache: function () { this.clearCacheStatus = 'loading'; let data = new FormData(); data.append('action', 'sbi_clear_cache'); data.append('model', JSON.stringify(this.model)); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.clearCacheStatus = 'error'; return; } this.cronNextCheck = data.data.cronNextCheck; this.clearCacheStatus = 'success'; setTimeout(function () { this.clearCacheStatus = null; }.bind(this), 3000); }); }, installAutomatorPlugin: function(ispluginInstalled, isPluginActive, pluginDownloadPath, automatorPlugin) { var self = this; self.automatorInstallBtnStatus = 'loading'; self.disableAutomatorBtn = true; let data = new FormData(); data.append( 'action', ! ispluginInstalled ? 'sbi_install_addon' : 'sbi_activate_addon' ); data.append( 'nonce', self.nonce ); data.append( 'type', 'plugin' ); data.append( 'plugin', ! ispluginInstalled ? pluginDownloadPath : automatorPlugin ); fetch(self.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if ( data.success === true ) { self.automatorInstallBtnStatus = 'success'; self.enableAutomatorSetupStep = true; } else { self.automatorInstallBtnStatus = 'normal'; self.disableAutomatorBtn = false; } }); }, dismissAutomatorNotice: function() { var self = this; // Remove the notice instantly from the UI for better user experience self.uncannyAutomatorScreen.shouldHideAutomatorNotice = true; let data = new FormData(); data.append( 'action', 'sbi_dismiss_automator_notice' ); data.append( 'nonce', self.nonce ); fetch(self.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) }, automatorInstallBtnIcon: function() { if ( this.automatorInstallBtnStatus == 'loading' ) { return this.loaderSVG; } else if ( this.automatorInstallBtnStatus == 'success' ) { return this.checkmarCircleSVG; } else if ( this.automatorInstallBtnStatus == 'error' ) { return this.timesSVG; } if ( this.uncannyAutomatorScreen.isPluginInstalled && this.uncannyAutomatorScreen.isPluginActive ) { return this.checkmarCircleSVG; } return this.uncannyAutomatorScreen.installSVG; }, automatorInstallBtnText: function() { if ( this.automatorInstallBtnStatus == 'loading' ) { return 'Installing'; } else if ( this.automatorInstallBtnStatus == 'success' ) { return 'Installed & Activated Successfully'; } if ( this.uncannyAutomatorScreen.isPluginInstalled && !this.uncannyAutomatorScreen.isPluginActive ) { return 'Activate Plugin'; } if ( this.uncannyAutomatorScreen.isPluginInstalled && this.uncannyAutomatorScreen.isPluginActive ) { return 'Plugin Installed & Activated'; } return 'Install Plugin'; }, setupAutomatorPlugin: function() { var self = this; let data = new FormData(); data.append( 'action', 'sbi_automator_setup_source' ); data.append( 'nonce', self.nonce ); fetch(self.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if ( data.success === true ) { window.location.href = self.adminUrl + self.uncannyAutomatorScreen.setupPage; } }); }, showTooltip: function (tooltipName) { this.tooltipName = tooltipName; }, hideTooltip: function () { this.tooltipName = null; }, gdprOptions: function () { this.gdprInfoTooltip = null; }, gdprLimited: function () { this.gdprInfoTooltip = this.gdprInfoTooltip == null ? true : null; }, clearImageResizeCache: function () { this.optimizeCacheStatus = 'loading'; let data = new FormData(); data.append('action', 'sbi_clear_image_resize_cache'); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.optimizeCacheStatus = 'error'; return; } this.optimizeCacheStatus = 'success'; setTimeout(function () { this.optimizeCacheStatus = null; }.bind(this), 3000); }); }, resetErrorLog: function () { this.clearErrorLogStatus = 'loading'; let data = new FormData(); data.append('action', 'sbi_clear_error_log'); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (!data.success) { this.clearErrorLogStatus = 'error'; return; } this.clearErrorLogStatus = 'success'; setTimeout(function () { this.clearErrorLogStatus = null; }.bind(this), 3000); }); }, dpaReset: function () { this.dpaResetStatus = 'loading'; let data = new FormData(); data.append('action', 'sbi_dpa_reset'); data.append('nonce', this.nonce); fetch(this.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (data.success == false) { this.dpaResetStatus = 'error'; return; } this.dpaResetStatus = 'success'; setTimeout(function () { this.dpaResetStatus = null; }.bind(this), 3000); }); }, resetErrorLogIcon: function () { if (this.clearErrorLogStatus === null) { return; } if (this.clearErrorLogStatus == 'loading') { return this.loaderSVG; } else if (this.clearErrorLogStatus == 'success') { return this.checkmarkSVG; } else if (this.clearErrorLogStatus == 'error') { return this.timesCircleSVG; } }, saveChangesIcon: function () { if (this.btnStatus === 'loading') { return this.loaderSVG; } else if (this.btnStatus === 'success') { return this.checkmarkSVG; } else if (this.btnStatus === 'error') { return this.timesCircleSVG; } }, importBtnIcon: function () { if (this.uploadStatus === null) { return this.uploadSVG; } if (this.uploadStatus == 'loading') { return this.loaderSVG; } else if (this.uploadStatus == 'success') { return this.checkmarkSVG; } else if (this.uploadStatus == 'error') { return this.timesCircleSVG; } }, clearCacheIcon: function () { if (this.clearCacheStatus === null) { return this.reloadSVG; } if (this.clearCacheStatus == 'loading') { return this.loaderSVG; } else if (this.clearCacheStatus == 'success') { return this.checkmarkSVG; } else if (this.clearCacheStatus == 'error') { return this.timesCircleSVG; } }, clearImageResizeCacheIcon: function () { if (this.optimizeCacheStatus === null) { return; } if (this.optimizeCacheStatus == 'loading') { return this.loaderSVG; } else if (this.optimizeCacheStatus == 'success') { return this.checkmarkSVG; } else if (this.optimizeCacheStatus == 'error') { return this.timesCircleSVG; } }, dpaResetStatusIcon: function () { if (this.dpaResetStatus === null) { return; } if (this.dpaResetStatus == 'loading') { return this.loaderSVG; } else if (this.dpaResetStatus == 'success') { return this.checkmarkSVG; } else if (this.dpaResetStatus == 'error') { return this.timesCircleSVG; } }, /** * Toggle Sticky Widget view * * @since 4.0 */ toggleStickyWidget: function () { this.stickyWidget = !this.stickyWidget; }, printUsedInText: function (usedInNumber) { if (usedInNumber == 0) { return this.genericText.sourceNotUsedYet; } return this.genericText.usedIn + ' ' + usedInNumber + ' ' + (usedInNumber == 1 ? this.genericText.feed : this.genericText.feeds); }, /** * Delete Source Ajax * * @since 4.0 */ deleteSource: function (sourceToDelete) { var self = this; let data = new FormData(); data.append('action', 'sbi_feed_saver_manager_delete_source'); data.append('source_id', sourceToDelete.id); data.append('username', sourceToDelete.username); data.append('nonce', this.nonce); fetch(self.ajaxHandler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if (sourceToDelete.just_added) { window.location.href = window.location.href.replace('sbi_access_token', 'sbi_null'); } self.sourcesList = data; }); }, /** * Check if Value is Empty * * @since 4.0 * * @return boolean */ checkNotEmpty: function (value) { return value != null && value.replace(/ /gi, '') != ''; }, /** * Activate View * * @since 4.0 */ activateView: function (viewName, sourcePopupType = 'creation', ajaxAction = false) { var self = this; self.viewsActive[viewName] = (self.viewsActive[viewName] == false) ? true : false; if (viewName == 'sourcePopup' && sourcePopupType == 'creationRedirect') { setTimeout(function () { self.$refs.addSourceRef.processIFConnect() }, 3500); } }, /** * Switch & Change Feed Screens * * @since 4.0 */ switchScreen: function (screenType, screenName) { this.viewsActive[screenType] = screenName; }, /** * Parse JSON * * @since 4.0 * * @return jsonObject / Boolean */ jsonParse: function (jsonString) { try { return JSON.parse(jsonString); } catch (e) { return false; } }, /** * Ajax Post Action * * @since 4.0 */ ajaxPost: function (data, callback) { var self = this; self.$http.post(self.ajaxHandler, data).then(callback); }, /** * Check if Object has Nested Property * * @since 4.0 * * @return boolean */ hasOwnNestedProperty: function (obj, propertyPath) { if (!propertyPath) { return false; } var properties = propertyPath.split('.'); for (var i = 0; i < properties.length; i++) { var prop = properties[i]; if (!obj || !obj.hasOwnProperty(prop)) { return false; } else { obj = obj[prop]; } } return true; }, /** * Show Tooltip on Hover * * @since 4.0 */ toggleElementTooltip: function (tooltipText, type, align = 'center') { var self = this, target = window.event.currentTarget, tooltip = (target != undefined && target != null) ? document.querySelector('.sb-control-elem-tltp-content') : null; if (tooltip != null && type == 'show') { self.tooltip.text = tooltipText; var position = target.getBoundingClientRect(), left = position.left + 10, top = position.top - 10; tooltip.style.left = left + 'px'; tooltip.style.top = top + 'px'; tooltip.style.textAlign = align; self.tooltip.hover = true; } if (type == 'hide') { self.tooltip.hover = false; } }, /** * Hover Tooltip * * @since 4.0 */ hoverTooltip: function (type) { this.tooltip.hover = type; }, /** * Open Dialog Box * * @since 4.0 */ openDialogBox: function (type, args = []) { var self = this, heading = self.dialogBoxPopupScreen[type].heading, description = self.dialogBoxPopupScreen[type].description, customButtons = self.dialogBoxPopupScreen[type].customButtons; switch (type) { case "deleteSource": self.sourceToDelete = args; heading = heading.replace("#", self.sourceToDelete.username); break; } self.dialogBox = { active: true, type: type, heading: heading, description: description, customButtons: customButtons }; }, /** * Confirm Dialog Box Actions * * @since 4.0 */ confirmDialogAction: function () { var self = this; switch (self.dialogBox.type) { case 'deleteSource': self.deleteSource(self.sourceToDelete); break; } }, /** * Display Feed Sources Settings * * @since 4.0 * * @param {object} source * @param {int} sourceIndex */ displayFeedSettings: function (source, sourceIndex) { this.expandedFeedID = sourceIndex + 1; }, /** * Hide Feed Sources Settings * * @since 4.0 * * @param {object} source * @param {int} sourceIndex */ hideFeedSettings: function () { this.expandedFeedID = null; }, /** * Copy text to clipboard * * @since 4.0 */ copyToClipBoard: function (value) { var self = this; const el = document.createElement('textarea'); el.className = 'sbi-fb-cp-clpboard'; el.value = value; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el); self.notificationElement = { type: 'success', text: this.genericText.copiedClipboard, shown: "shown" }; setTimeout(function () { self.notificationElement.shown = "hidden"; }, 3000); }, escapeHTML: function (text) { return text.replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }, /** * View Source Instances * * @since 4.0 */ viewSourceInstances: function (source) { var self = this; self.viewsActive.instanceSourceActive = source; }, /** * Return Page/Group Avatar * * @since 4.0 * * @return string */ returnAccountAvatar: function (source) { if (typeof source.local_avatar_url !== "undefined" && source.local_avatar_url !== '') { return source.local_avatar_url; } if (typeof source.avatar_url !== "undefined" && source.avatar_url !== '') { return source.avatar_url; } return false; }, /** * Trigger & Open Personal Account Info Dialog * * @since 6.0.8 * * @return string */ openPersonalAccount: function (source) { let self = this; self.$refs.personalAccountRef.personalAccountInfo.id = source.account_id; self.$refs.personalAccountRef.personalAccountInfo.username = source.username; self.$refs.personalAccountRef.personalAccountInfo.bio = source?.header_data?.biography; self.$refs.personalAccountRef.personalAccountPopup = true; self.$refs.personalAccountRef.step = 2; }, /** * Cancel Personal Account * * @since 6.0.8 */ cancelPersonalAccountUpdate: function () { }, successPersonalAccountUpdate: function () { let self = this; self.notificationElement = { type: 'success', text: self.genericText.personalAccountUpdated, shown: "shown" }; setTimeout(function () { self.notificationElement.shown = "hidden"; }, 3000); sbiSettings.$forceUpdate(); }, } }); admin/assets/js/about.js000064400000012230150515074560011230 0ustar00var extensions_data = { genericText: sbi_about.genericText, links: sbi_about.links, extentions_bundle: sbi_about.extentions_bundle, supportPageUrl: sbi_about.supportPageUrl, plugins: sbi_about.pluginsInfo, stickyWidget: false, socialWallActivated: sbi_about.socialWallActivated, socialWallLinks: sbi_about.socialWallLinks, recommendedPlugins: sbi_about.recommendedPlugins, social_wall: sbi_about.social_wall, aboutBox: sbi_about.aboutBox, ajax_handler: sbi_about.ajax_handler, nonce: sbi_about.nonce, buttons: sbi_about.buttons, icons: sbi_about.icons, btnClicked: null, btnStatus: null, btnName: null, } var sbiAbout = new Vue({ el: "#sbi-about", http: { emulateJSON: true, emulateHTTP: true }, data: extensions_data, methods: { activatePlugin: function( plugin, name, index, type ) { this.btnClicked = index + 1; this.btnStatus = 'loading'; this.btnName = name; let data = new FormData(); data.append( 'action', 'sbi_activate_addon' ); data.append( 'nonce', this.nonce ); data.append( 'plugin', plugin ); data.append( 'type', 'plugin' ); if ( this.extentions_bundle && type == 'extension' ) { data.append( 'extensions_bundle', this.extentions_bundle ); } fetch(this.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { if ( name === 'social_wall' ) { this.social_wall.activated = true; } else if ( type === 'recommended_plugin' ) { this.recommendedPlugins[name].activated = true; } else { this.plugins[name].activated = true; } this.btnClicked = null; this.btnStatus = null; this.btnName = null; } }); }, deactivatePlugin: function( plugin, name, index, type ) { this.btnClicked = index + 1; this.btnStatus = 'loading'; this.btnName = name; let data = new FormData(); data.append( 'action', 'sbi_deactivate_addon' ); data.append( 'nonce', this.nonce ); data.append( 'plugin', plugin ); data.append( 'type', 'plugin' ); if ( this.extentions_bundle && type == 'extension' ) { data.append( 'extensions_bundle', this.extentions_bundle ); } fetch(this.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { if ( name === 'social_wall' ) { this.social_wall.activated = false; } else if ( type === 'recommended_plugin' ) { this.recommendedPlugins[name].activated = false; } else { this.plugins[name].activated = false; } this.btnClicked = null; this.btnName = null; this.btnStatus = null; } return; }); }, installPlugin: function( plugin, name, index, type ) { this.btnClicked = index + 1; this.btnStatus = 'loading'; this.btnName = name; let data = new FormData(); data.append( 'action', 'sbi_install_addon' ); data.append( 'nonce', this.nonce ); data.append( 'plugin', plugin ); data.append( 'type', 'plugin' ); fetch(this.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { if ( type === 'recommended_plugin' ) { this.recommendedPlugins[name].installed = true; this.recommendedPlugins[name].activated = true; } else { this.plugins[name].installed = true; this.plugins[name].activated = true; } this.btnClicked = null; this.btnName = null; this.btnStatus = null; } return; }); }, buttonIcon: function() { if ( this.btnStatus == 'loading' ) { return this.icons.loaderSVG } }, /** * Toggle Sticky Widget view * * @since 4.0 */ toggleStickyWidget: function() { this.stickyWidget = !this.stickyWidget; }, } })admin/assets/js/admin-notifications.js000064400000010071150515074560014056 0ustar00/** * CFF Admin Notifications. * * @since 2.18 */ 'use strict'; var SBIAdminNotifications = window.SBIAdminNotifications || ( function( document, window, $ ) { /** * Elements holder. * * @since 2.18 * * @type {object} */ var el = { $notifications: $( '#sbi-notifications' ), $nextButton: $( '#sbi-notifications .navigation .next' ), $prevButton: $( '#sbi-notifications .navigation .prev' ), $adminBarCounter: $( '#wp-admin-bar-wpforms-menu .sbi-menu-notification-counter' ), $adminBarMenuItem: $( '#wp-admin-bar-sbi-notifications' ), }; /** * Public functions and properties. * * @since 2.18 * * @type {object} */ var app = { /** * Start the engine. * * @since 2.18 */ init: function() { el.$notifications.find( '.messages a').each(function() { if ($(this).attr('href').indexOf('dismiss=') > -1 ) { $(this).addClass('button-dismiss'); } }) $( app.ready ); }, /** * Document ready. * * @since 2.18 */ ready: function() { app.updateNavigation(); app.events(); }, /** * Register JS events. * * @since 2.18 */ events: function() { el.$notifications .on( 'click', '.dismiss', app.dismiss ) .on( 'click', '.button-dismiss', app.buttonDismiss ) .on( 'click', '.next', app.navNext ) .on( 'click', '.prev', app.navPrev ); }, /** * Click on a dismiss button. * * @since 2.18 */ buttonDismiss: function( event ) { event.preventDefault(); app.dismiss(); }, /** * Click on the Dismiss notification button. * * @since 2.18 * * @param {object} event Event object. */ dismiss: function( event ) { if ( el.$currentMessage.length === 0 ) { return; } // Update counter. var count = parseInt( el.$adminBarCounter.text(), 10 ); if ( count > 1 ) { --count; el.$adminBarCounter.html( '' + count + '' ); } else { el.$adminBarCounter.remove(); el.$adminBarMenuItem.remove(); } // Remove notification. var $nextMessage = el.$nextMessage.length < 1 ? el.$prevMessage : el.$nextMessage, messageId = el.$currentMessage.data( 'message-id' ); if ( $nextMessage.length === 0 ) { el.$notifications.remove(); } else { el.$currentMessage.remove(); $nextMessage.addClass( 'current' ); app.updateNavigation(); } // AJAX call - update option. var data = { action: 'sbi_dashboard_notification_dismiss', nonce: sbi_admin.nonce, id: messageId, }; $.post( sbi_admin.ajax_url, data, function( res ) { if ( ! res.success ) { //sbiAdmin.debug( res ); } } ).fail( function( xhr, textStatus, e ) { //sbiAdmin.debug( xhr.responseText ); } ); }, /** * Click on the Next notification button. * * @since 2.18 * * @param {object} event Event object. */ navNext: function( event ) { if ( el.$nextButton.hasClass( 'disabled' ) ) { return; } el.$currentMessage.removeClass( 'current' ); el.$nextMessage.addClass( 'current' ); app.updateNavigation(); }, /** * Click on the Previous notification button. * * @since 2.18 * * @param {object} event Event object. */ navPrev: function( event ) { if ( el.$prevButton.hasClass( 'disabled' ) ) { return; } el.$currentMessage.removeClass( 'current' ); el.$prevMessage.addClass( 'current' ); app.updateNavigation(); }, /** * Update navigation buttons. * * @since 2.18 */ updateNavigation: function() { el.$currentMessage = el.$notifications.find( '.message.current' ); el.$nextMessage = el.$currentMessage.next( '.message' ); el.$prevMessage = el.$currentMessage.prev( '.message' ); if ( el.$nextMessage.length === 0 ) { el.$nextButton.addClass( 'disabled' ); } else { el.$nextButton.removeClass( 'disabled' ); } if ( el.$prevMessage.length === 0 ) { el.$prevButton.addClass( 'disabled' ); } else { el.$prevButton.removeClass( 'disabled' ); } }, }; return app; }( document, window, jQuery ) ); // Initialize. SBIAdminNotifications.init(); admin/builder/templates/preview/header.php000064400000006002150515074560014710 0ustar00
{{customizerFeedData.header.fan_count}}

{{customizerFeedData.header.name}}

{{customizerFeedData.header.about}}

Comments Box SVG iconsUsed for the like, share, comment, and reaction iconsadmin/builder/templates/preview/error.php000064400000001310150515074560014606 0ustar00
admin/builder/templates/preview/theme-styles.php000064400000000423150515074560016104 0ustar00is_cached() ) { $theme_css->load_css(); $theme_css->parse(); $theme_css->find_styles(); $theme_css->cache(); } echo $theme_css->generate_style_html();admin/builder/templates/wizard.php000064400000001427150515074560013305 0ustar00
admin/builder/templates/onboarding/success-page.php000064400000012672150515074560016515 0ustar00

Upgrade Content Banner

admin/builder/templates/onboarding/configure-features.php000064400000005045150515074560017724 0ustar00

admin/builder/templates/onboarding/welcome.php000064400000001410150515074560015552 0ustar00

Welcome Banner
admin/builder/templates/onboarding/install-plugins.php000064400000003103150515074560017245 0ustar00

admin/builder/templates/onboarding/add-source.php000064400000010015150515074560016146 0ustar00

{{genericText.addNew}}
admin/builder/templates/sections/feeds-type.php000064400000003732150515074560015702 0ustar00

{{selectFeedTypeScreen.feedTypeHeading}}

{{selectFeedTypeScreen.mainDescription}}

{{feedTypeEl.description}}

{{selectFeedTypeScreen.advancedHeading}}PRO

{{advFeedTypeEl.title}}
admin/builder/templates/sections/feeds-list.php000064400000000613150515074560015667 0ustar00
{{customizerFeedData.feed_info.feed_name}}
{{genericText.help}}
admin/builder/templates/sections/create-feed/multiple-sources-list.php000064400000010330150515074560022256 0ustar00
{{hashtag}}
{{selectSourceScreen.hashtagGetBy}}
{{genericText.mostRecent}}
{{genericText.topRated}}
@{{selectedSource.username}}
admin/builder/templates/sections/create-feed/multiple-sources.php000064400000001545150515074560021315 0ustar00

{{selectSourceScreen.mainHeading}}

{{selectSourceScreen.description}}
{{genericText.addSourceType}}
admin/builder/templates/sections/create-feed/single-public-hashtags.php000064400000003332150515074560022332 0ustar00

{{selectSourceScreen.mainHashtagHeading}}

{{selectSourceScreen.hashtagDescription}}
{{hashtag}}
{{selectSourceScreen.hashtagGetBy}}
{{genericText.mostRecent}}
{{genericText.topRated}}
admin/builder/templates/sections/create-feed/single-sources.php000064400000007537150515074560020752 0ustar00

{{selectSourceScreen.mainHeading}}

{{selectSourceScreen.description}}
{{genericText.addSource}}
{{genericText.addNew}}

{{source.username}}
{{source.account_type}}
admin/builder/templates/sections/empty-state.php000064400000037203150515074560016111 0ustar00
1

{{welcomeScreen.createFeed}}

{{welcomeScreen.createFeedDescription}}

2

{{welcomeScreen.customizeFeed}}

{{welcomeScreen.customizeFeedDescription}}

3

{{welcomeScreen.embedFeed}}

{{welcomeScreen.embedFeedDescription}}

admin/builder/templates/sections/feeds/instances.php000064400000006355150515074560016716 0ustar00

{{viewsActive.instanceFeedActive.feed_name}}

TimeLine
{{genericText.page}} {{genericText.location}} {{allFeedsScreen.columns.shortcodeText}}
{{instance.page_text}} {{instance.html_location}}
{{instance.shortcode}}
{{(genericText.copy +' '+ genericText.shortcode).replace(/ /g," ")}}
{{genericText.page}} {{genericText.location}} {{allFeedsScreen.columns.shortcodeText}}
admin/builder/templates/sections/feeds/feeds.php000064400000013517150515074560016013 0ustar00
{{feedPagination.feedsCount +' '+ (feedPagination.feedsCount > 1 ? genericText.items : genericText.item)}}
{{feedPagination.currentPage}} of {{feedPagination.pagesNumber}}
{{allFeedsScreen.columns.nameText}} {{allFeedsScreen.columns.shortcodeText}} {{allFeedsScreen.columns.instancesText}} {{allFeedsScreen.columns.actionsText}}
{{feed.feed_name}} {{feed.settings.type}}
[instagram-feed feed={{feed.id}}]
{{(genericText.copy +' '+ genericText.shortcode).replace(/ /g," ")}}
{{genericText.usedIn}} {{feed.instance_count + ' ' + (feed.instance_count !== 1 ? genericText.places : genericText.place)}}
{{genericText.clickViewInstances.replace(/ /g," ")}}
{{genericText.edit.replace(/ /g," ")}}
{{allFeedsScreen.columns.nameText}} {{allFeedsScreen.columns.shortcodeText}} {{allFeedsScreen.columns.instancesText}} {{allFeedsScreen.columns.actionsText}}
admin/builder/templates/sections/feeds/legacy-feeds.php000064400000017054150515074560017255 0ustar00
{{genericText.new}}
{{allFeedsScreen.onboarding.getStarted}}

{{allFeedsScreen.legacyFeeds.heading}}

{{allFeedsScreen.legacyFeeds.toolTip}}
{{genericText.settings}}
{{allFeedsScreen.columns.nameText}} {{allFeedsScreen.columns.shortcodeText}} {{allFeedsScreen.columns.instancesText}} {{allFeedsScreen.columns.actionsText}}
{{legacyFeed.feed_name}} {{legacyFeed.feed_type}}
{{legacyFeed.shortcode}}
{{(genericText.copy +' '+ genericText.shortcode).replace(/ /g," ")}}
{{genericText.usedIn}} {{legacyFeed.instance_count + ' ' + (legacyFeed.instance_count !== 1 ? genericText.places : genericText.place)}}
{{genericText.clickViewInstances.replace(/ /g," ")}}
{{viewsActive.legacyFeedsShown ? allFeedsScreen.legacyFeeds.hide : allFeedsScreen.legacyFeeds.show}}
admin/builder/templates/sections/footer.php000064400000052433150515074560015135 0ustar00
Loading...
admin/builder/templates/sections/customizer/preview.php000064400000001523150515074560017516 0ustar00
admin/builder/templates/sections/customizer/sidebar.php000064400000014414150515074560017451 0ustar00
{{tab.heading}}
{{section.heading}}
{{section.heading}}

admin/builder/templates/sections/popup/onboarding-popup.php000064400000006570150515074560020266 0ustar00

{{tooltip.heading}}

{{tooltip.p}}

{{tooltip.step}}/{{allFeedsScreen.onboarding.tooltips.length}}
{{genericText.previous}}
{{genericText.next}}
{{genericText.finish}}
admin/builder/templates/sections/popup/add-source-popup.php000064400000062447150515074560020177 0ustar00 admin/builder/templates/sections/popup/confirm-dialog-popup.php000064400000003727150515074560021037 0ustar00 admin/builder/templates/sections/popup/embed-popup.php000064400000011146150515074560017213 0ustar00

{{embedPopupScreen.heading}}

{{embedPopupScreen.description}}

{{embedPopupScreen.addPage}}

{{embedPopupScreen.selectPage}}
{{page.title}}
admin/builder/templates/sections/popup/extensions-popup.php000064400000010120150515074560020325 0ustar00

{{genericText.liteFeedUsers}}

{{extensionsPopup[viewsActive.extensionsPopupElement].bullets.heading}}

{{bullet}}
admin/builder/templates/sections/popup/feedtypes-popup.php000064400000006043150515074560020127 0ustar00
{{genericText.back}}

{{selectFeedTypeScreen.anotherFeedTypeHeading}}

{{feedTypeEl.description}}

{{feedTypeEl.description}}
admin/builder/templates/sections/popup/personal-account-popup.php000064400000006020150515074560021407 0ustar00 admin/builder/templates/sections/popup/install-plugin-popup.php000064400000010153150515074560021076 0ustar00 admin/builder/templates/sections/popup/uncanny-automator-integraion.php000064400000004664150515074560022626 0ustar00

{{uncannyAutomatorScreen.heading}}

{{uncannyAutomatorScreen.description}}

{{uncannyAutomatorScreen.installStep.title}}

{{uncannyAutomatorScreen.installStep.description}}

{{uncannyAutomatorScreen.setupStep.title}}

{{uncannyAutomatorScreen.setupStep.description}}

admin/builder/templates/sections/popup/onboarding-customizer-popup.php000064400000006116150515074560022464 0ustar00

{{tooltip.heading}}

{{tooltip.p}}

{{tooltip.step}}/{{customizeScreensText.onboarding.tooltips.length}}
{{genericText.previous}}
{{genericText.next}}
{{genericText.finish}}
admin/builder/templates/sections/popup/feedtypes-customizer-popup.php000064400000003357150515074560022336 0ustar00

{{genericText.editSources}}

{{genericText.addSourceType}}
admin/builder/templates/sections/popup/source-instances.php000064400000006251150515074560020264 0ustar00

{{viewsActive.instanceSourceActive.username}}

{{viewsActive.instanceSourceActive.account_type}}
{{genericText.feedName}} {{genericText.id}} {{genericText.shortcodeText}}
{{instance.feed_name}} {{instance.id}}
{{(genericText.copy +' '+ genericText.shortcode).replace(/ /g," ")}}
{{genericText.feedName}} {{genericText.id}} {{genericText.shortcodeText}}
admin/builder/templates/sections/popup/sources-list-popup.php000064400000007757150515074560020610 0ustar00

{{genericText.addNew}}

{{source.username}}
{{source.account_type}}
admin/builder/templates/screens/customizer.php000064400000000703150515074560015647 0ustar00
admin/builder/templates/screens/welcome.php000064400000002532150515074560015100 0ustar00

{{welcomeScreen.mainHeading}}

{{genericText.addNew}}
admin/builder/templates/screens/select-feed.php000064400000003456150515074560015633 0ustar00

{{selectFeedTypeScreen.mainHeading}}

{{genericText.next}}
{{genericText.back}}
{{genericText.next}}
admin/builder/templates/screens/onboarding-wizard.php000064400000004460150515074560017067 0ustar00
Balloon

$step) { ?>
admin/builder/templates/builder.php000064400000001614150515074560013431 0ustar00
admin/builder/assets/img/photos.png000064400000001240150515074560013367 0ustar00PNG  IHDRNe~PLTEݭkCۖΉξ۰ן[bwMksSGɶoN $tRNSu~IDATxR1a K0 /%PńX5gw; QEQEQEQEQEQEQEQEQEQEQ߿Mf^BMy}z~TO e"~\6EWD$o"̝H w"܉$s'+o"DRINWDRINI$2Q$ZHjl.*QDos̒Et%_LTQ !2f"YfsEY5h^[$*[G"EϺ'KU-&/Ke"5w"EHXUNNNdX܉GRxf{{uk>j R D֥=C#ZsQ ZwuGpSa)`??????????;U>IENDB`admin/builder/assets/img/allinoneseo.png000064400000002024150515074560014364 0ustar00PNG  IHDRr ߔ pHYs  sRGBgAMA aIDATxV[l aٵKZm- uxn/$Bں$ъ[ n %CD#hwRVeGٵߙY4mIvs?.WV\B8Jcek&-,.U!d ȘGH, 9HYfR蓰(q!Pk7+``\;`yxVeUo7G 0銆xsȇ%Y6)FYKUmRkQ0|!"^&pUxy"c:(Ddhw ľO$U#=8P1udˤn-8 {b߃ '9/Qw. Zc[;39?^jioƟ =+t~ޏuꁔB +6O o "Ӄmxym;I}/e;gu7t@`ѤtWUݢ8s_R}FrmH2ތi;e|Gy*gfnCc(ٝ#[5-jEg)cܚ>c:]ᆭjL%҅hJ8W':Yn.vsW /Z36#ch6?E3t`ra-逌0(!^ y2ԭS ySwdޠh~D;oE!e\:7EQs+[yaw{Wx<kbx6R2;aDm ጱ9oEKvnJ Q=]Tga"$ tMLMX)Q=K9;pO~M%"Nݓ9muۤ7SV*G8 _mU;."E0o'FFLw$-}HRQFכ۳86jW.0PͯSLw?Z&0IENDB`admin/builder/assets/img/dummy-lightbox.jpeg000064400000605773150515074560015212 0ustar00JFIFC    "##! %*5-%'2( .?/279<<<$-BFA:F5;<9C  9& &99999999999999999999999999999999999999999999999999p8" B /;Iv,7a)]}WWh:MɞG:aJf9ZR%.ŪUᤩ~56)9Z͠KdכKU6~d,FKu+w'"ӑ.Nr\+yMFp[kӍ"O8vQ:󾡆`2d]Ye}aʧ3MV((P{Bļѵ[du8~?pd 96D5űEP043'|O#@k;Hyhaԋ d/9u(zgԧR脄g*MŔQo xJt8lsPZ1֤ѣR|àVΈKJ H+Ż4I+}^Oz9S$QZ:Rݹ'|^3hreP9^y\ ʴzR`2Ѭ^44)/SFڶ vb׉z]J2 7΃WCf3uQa LeR+Ti@9O!%8JtOHJ/YU,&^}v/s]yÊZq]~^w("dעVzf#ϫ/>HztV"!e8TYfG(Bn@S"<J@(`3+˨`:\ovT4OsD7-VKrˍ*͡.߳#&^?>kgJmHMw 2Ip; ZUs'ӕ^{M I7TdY,Qv rR6BJa;+Slw#lוAVfV{59U̥^S|VI6 'W8؜}񦳅)|um,qŒͿ-u_K( ԤkژrMg-='z=?]yA-{?eoW /#:)0צ(Vwh 1Oԗ?nv:):Y*g2aY1*Ll{PுQfd^n(PSrOu'=:#b-Q:.HՉ9ޟn{b9>awF99nlg}Gvr'lnӯ8D? (wkȱ𾕒nnE J l`M]HȢd6XHt^:I[]. ortr=*N)jzktTA=O蓦YK=ZίVHwܗW*6^4P J)ꂬ#޴M(kqRѬ˰%T3LVAVD>J;ixp|պD[gwBޝUdm8GresJti:HJ*zh-IvURC Te +Ṗ\"> JJ0:t+#USڗGUf8Xg16ϦUR.oR?5Oˍf+៬ɥ :GRt ,Щ˾!{4A9;G<_+VZGQK@T9ytSEeɊaA[RyAc~txJlzl,UKJn,]%,M:( VZhӆ]J-'Իq쫜bgE=עSyi$cil9(V,9Y)F:vx΅ W׍u{V7:s\>'Gw@,#ܾJyToŞdfh'z3ua5B|PI*;I{u<de[ӊ^s 3kBY  JdX0K3A]AâQ-EMg=xԙA[i&R̂^g;=F,KAs6߆5{8Lʵ:\W$c}65hud XAz <7K=ub|"c`*54^/+5A+θ3HNtdԞk_g=FlAɋIt5y ^d]9u^O]3PIO;?N.½f'yRgZ)c-m+?&ES#g5<Ԗ3+.KfxTrC+{ߨWlgYTJ2‰m.oҬ^m Tj+<6YZ|כF{*܎zf'Dwsߔ3NaV})1b}T;Iv+3,gg첞y=p |:)s&* '_=/=~B"2?9J֧PCNy#̐qHsj( A |)h^Zo>O@/ld5Tyz+g~6PI^sDLߛ[ufE!<aK#<<@] ifam)Q'/zot1.z{Zs2^q0wh)M 4:WDlhT3gp_.蹖Zi&nȒs,ʫgBuQ9oJLisT'ܹU>IFQmabV ơ=)D#[H*}%/7R[9KMt2[R+zlZͨWAŎI>>b;B{Q2,VjmoF*ϱA[\l2uEVVkA]9oy,8c(R_vS,EVUh<fLO4ajyf~QȉVqm3f&)p!eg;(=1S">GIy7Df# GaMAu(?vm*&Q}mk<QN3t+nY(LdhȷOW҂uQ%q4ľ8&=-i:ŮMmOdm'}OuK]O#EAg 2.Jң5{jRjYQf@k^j6#k`F+ڟL}A> *FrDjnCẋybx rZV`6eJu0, K|f:{V~f8˹r`5^iZ>3S6͛]Z%5y27':%-64)?:M7i}CN:Isy2:>nhVW`Pօq7KHS{hS[k>7B-u[?z,o7r|Ok휬Al,"(]-}o6FlrEyO5oKY6-Iew, 3a+N|3;y}=DؑكVwoNkI/:Q|`-%^qN7X:sΊ{:Y6,ri;Qa3p.藛3UE$LHβ vg!zYUac`'-+5OfyQ0ۃ+vKɵ!1sn.r;0k~k$P^Ȉ< ^N {_/* {KE2wו 8iFgOFdn2&aZ\p7P [|Ͼ;08EfMM}X Pb tŔ]T6z";]G[260.aY1d3YNЦqtwDjBT(e78Ncnw&.q ܉^6^rd͎q}zV ?3aE~gԧ}+ )Plu:ϸ=Z84 de>X0h.Tch"ͥvlTXXlހ}Tva?,.xw۟o YLn3jY0UT8K"!Jej.M]7AKO羽B"ؗOⰎ ߰1N>+WjYiU|5f޷hY/A#]"//~vCB2e$ڈleT>6p(/8ǚܺeϽ7QÑg Pr64.-fY+'_sjFDM%F`*F#TwNi a+ˬߗb(92"tPx(++oCw?P5˪|Ƀ:$J+klI4&R+%_:Jl@0L-x啫*jV#n{O-^f[G"5bшd*Dcʵ2)#k)Xؚ̖ g؄AzG#2Z{R<4zs7(cRgSITHq~>RﴛmZĹ^u/8%j_jVSei_H~W])N-E/kq}!R"̥&RoBҵMm'm٤9"T"deXN&) Jz"Cڬ`Jotg84B+\ZluYZ63- hK#f' քkҺ4Ηi`2N;]1F׷?Yg^ |cK3.|٧2fOR9s\qz ˫U4ȓnZd4d Q9fP]^sO$ 3z^5[T_6`;තJ;3gQJF}U:(FT BBVpyլyi=Iy2[(z/dM௿yzLX CޟI&Y'?}peYv[Zz財U̸'0, ;]1UlR- |g(Nh1Bt*2uVVMiS;nW}>Ԅs;їW:8bVZ9n3U|d> Ck3)FRryF\K~7VW$j"~tOfΉMlYd?3ryצVuz>RKi4&ROhu`ف|y]Mcg`Xk'MwgXe=} Y'q ll&EB&yܜۛr5tMwgXV<Y,ʛIIb{mއEQb9Q?Pݜ2sZ-]a&EԜG2>N-Jl57bGX ]SG!e iС3'.L is\W;<:(io9qjo!T~hes:Ɍ ; ef}_. LY\~vWup2CcmTDEu,& <̠SlCc>׵IB{?]ZdsHW%Z*m$d߿eմm4؃d _%Q]l=\B*pܑ#ZܯV?Y-<7war5~ZLI6665;lLlK,kiQjt :}SYn [. Fo}w U;>֓&gakZ*=i"ޛUǚb{/#:PMѯY6V]ũqJ@) kx*ifje%Cf;Αy6䍂3Γ<̺RӧSuqz]eB VYbx|!5K+VܯK}?,rwR*UP%t Z<4]:V@Beхb̀eҠy;<^>vF@[[G!ga sujϹ=GVfGR[-b`|A,6gisʾ2j Nkf .< (yQd U 3=x 67RPy\K4:o2ḾkHqfm"p閈ɮf+,STOI'zd/i)#93t}&`j\>qyWS;|ʇ~|T&f2ٳ*TIGYKIf= ZR茊Y>|ν_}R[WrG{Ŵdx}Mu һ4:O`e&V/*> ̪.Te5>%cb[KT֠n^_MGԥ&EFVZ-g謚y>^S·ی3*Տ얼Kc؏uP|û)(uA>uh5Vq_-fW+g<kR2qe .ʾQ`W=EÁg+"ur:dS範/+^N3yAy5¨yN"ǺgnHw<̌^6lkMy#biPGVVzGYim}ɫ ]ebOQDQnO=dm=j@8}lIT2?Kf_d˞ں>,}>PJ6#'<<\f@?jk˾l?7O ɂ*q`It6'r<}(H4^O=>Jϼ^q(,Ȧcᮃi>qV5BCH>(gVc}eRDZi+ĪY{%ar95{UyEA_ⷞFO9LkNz]ժXm5'lW9|L(/>ӟ =MW X&KDyja‚h3VOKFm2O ȘRfYR8$#fN=*G (,f|?b: 2e]K#2/i}Ne$hI.1OI+ӥyo}Vu#-pQY{6X)My֧JbfĶKq?^1h?:馰=;ҕ::~uiXѼ ]K;9H%eyEp{uN]#rxg+( oF5!ehtRRepHvR$U5H&w8)od?eOl]7>cm=Z?$}}љFJT@Βν eZ"nW`tʦUHO 2{U:*#jYuZF[g\*/Leʞ L؆~_`^z֬ʨYu?AoW_)? Xuߝv3dm65wc>Ώ=Ygw:ڸ'4'ȱG"ZXA0(I]/nm;QiYL}Yϳ; AT+(~E׉e'!յ'aQ+;΍Hy]A>s-Y# ztMQ=T3ͲP/=A|I{#ߝ=Ayyco\iT%ds]畕+g:9j}5O$ 4uhXA3lgIz9lX j7 Ɂ&j-W{]n#J&-=+*Eʢmn(+&O8f6's#WTȽlaKysvP['[ҔJ jQz#&gE!RK`0euKJ4#HA7 ]$& `pd‚*^E0]'K t:G%M鐒:I,/7AB=+emA}kkщ5|䉜 3D4ϕh]cR`}FK#5+PLIj3f'QhSҪ-QJbh;6-F.8Q$ͅFO~גf r0ݙf=$`]t?6VMS t(OO}׋HþTCml{Y)" @p{>+>w1,fC1~n:C&9zDg-ewAt<|Oϩ*/ tou43O$ R yVc!լK7/D"òߝ& *6)t n~m>?-ƫRs6~Zh&VbPt&VN̘vԚ V  - fom]jn('6YL4VO-**%yH 3]P񽆽-:`t\-7ek>ͺדfSl\*k?w< ^7CIwqurqNGfYQز=]|PTUMo:jV^o@3ajdl΂)xut]fg qB'ǽ?Ҕ X. kl-ʤ2}?k+sLeaCrM +kP.fAϽ/ߍb`/ERzG4pYh,&Dbs\r{\ӡ?_u{2k+]n~iuK})W nP'(E¼QJ>ҥmyc{z I}]&ptm_?FclR#Mݟ @}ߺ;hz֜~T' rAQ@VK "ɒ{P.li O#lϕբ76X&ʅY-(sqo@ <^8]N^FYG$xD}1HiHEB[ ؉L'3}s$?['ym3+1C;AZ>>{Щ>F/-l< b08,,ymZd">:N7^Yj3S kiQU%n$+W¿?Dˈ{&ËLh80ڂ|ˏg̠?/ՋjP!M44 [,AacUCT~sJ??Ԓz%e[+ [B)K)HUynkfu'JK'?⪎[Je^?Qv_7j8H*;$rw4|%zOJnʼ#ʳY~dZoQz, >xfKZ?G!c{5'X]}ZϗeFLf 3*jTTembP!5Xi,MIgC]NcSMAf]T%(H5f@D6dz/2(-VX' B=>yO$y@v +w![;eNk"e1&EI.Ͻkˬ<霝zqqOޤv{ZLHli࣬wL)ʠVAij e\5~y).;73x5妼S:߅ -icsϧ뤁gũu5z4UW)Ah[0s&.~EnNM[fJ {zh6F; e=l[RFNr:5Fs?W~tRjbX!y_&]lȡVh<jJ銶tB{[i36zGﯟu("H~&KLe;Et"lcVȋ0|δ ]g"2tkmtFcxhUI?}ԆFcBAGƐy쮗.Kz! :` Egu2/;4i ;гLD _D=Oͺ.5%~YbesA:Mon,ܨ7\;)^X>bߛz ˞fS(GIzhЧyJ({M2x,)L( I3MCkXPL2ga5~:MC-tr$&H~k^u |nǟ鵯Yo8GT Bnt~\GV+ */kc${>{{gWz ߕD6|02EKa%t#hⷖ9^F%\35lͽ`ޖ oz<۫}/KSYdKSH6`8 +"`t }7z{ DqqS]X{h~.7R߸X gK:Fuq(0D0Ϟ6lx7Z܋uTg|/OAF%v5a6פ u|׆T4>({Bȧ^_g7}__PVo3(Pd*so g@}h L|2ia?m>+{e^_G2AOc>+àF=@T~7Sk\ w8d΂E5ixUG=QE葕GQMbEfk.Sߝ5<a )W\3C u3˰xhT/= MoCSYksg;k?L<$ײ/O3Kw䔗"_?~70#(cYYӛ~ +ofnkim鱱+,:7?/S=7tnvg+t3E4K8vOM2x0.s:|M &Z"<͙ (:Ȳ:̺t1 M owjΒC0 ޤ Dc&LųI _b7̃Lb`9y/-zHve^C>װ}{Dti$Mue廼\9n-t}*qkT48N矺#K߳*Avok:rL}7Ueʶ\<ާϓT~}E~(3jx(~y/1yki[\aF-Rk;2c>ͱ2"ߔQ`)V OzbeWmz<"տO\|'wWgMZ{zK2YߘO2asf@y26ZߌNj\}i^~7[b8载fhς8!Ս3U*pX:l38.}=:ut5˟^/LJ߀ײ1j\8W2-x~{ EI\ڼ.06Y 5.̎"^;$]G| Ľ]D=XL)`c]PMyyٵs,!"#12A$34B%CǭdgT^cȾwzc~$ҷiDp@FTCOFy;n:1Eq*,Vm=6b2qHż"nظ:ye>EZ0I\+zs~?0ޝ!&|DS$ROڧiO2Wsp_t7\vh{FtٖUZfm ]UALHc{NDiY3ZpFR/12'T.pq6 ^`WS_U7l3к#Cu)ٙ z J;*6 +@96DTAjd\#cwɍh" N`M Zh?D$E@*942c6RVi3iFStx-Rݞl< Dh6$_t P}b͈4'M!2f Z0F#?< WCXhd8Pciħ|#85U|tm5> 1%~Z:iGHh2v=H*z]4; QGxmWHD*Ђ:cZB'(Ҽ!1iu2@"}uQ^^1cI*yJHȑsO9ʡ/eWTJì#OҤHI!AnPlRiNeϬmѦT1ꗒW0B$E F[Qg)1ɣ@uR(&>U+dMM)~=o3c>lBSqy~ٓA34%O;;\slOz(5h}qSg*ʞI!NaR)۲cDi E_eytsHl}p6%+*cL "1Ƕv@XA k*3= ?!>TA 4j'_ebSĴ`cFd1k)3c>WE#Pі<'(&c+DpC$fp9?O +vK8 y#ĉ E%s9"`~C&9NN-0d` ?px$&ZX3,MwǩnȌΈ y댫41ף4~'@lHCUlh#Z;Б,RKưQR9uՑ>8,εc=Ij4Dܢ Jxi4>yp<%m|I +l\{{ }цKmS1 ]9Og"Yc ĉ/WO$iјo-[̆t$fc3 %!äk (w1V\c>4_)p*S1r%Mߣƺ^Rdi ئʩ V{`Ef8tbȈ[2>xR4\mv)/1Y"'jdd`JؙP6,b.sJl劀4I|kҔR!螓^WY#$igB jJcz7XiOz  PJc }jr% Sڟh)s}3З,4NQ= kT!K4]J`rDW:y`d@ڕD+y2Oy*w4aoړRr >&-_Ϝ2lxyJ&㷙1Noy#}hU+Whx81ӪDrdB,@f fJSꙉn|!2_&Y4<ȠX6 囿'IF}0ҝ4f+@ ͮ;m1,z/EnJjN@>" $K1IʷfϚVaA sʝcN_ܟfC(Վ0St= SN2z<4yhBnL'1T#,W0/!dLQ_S:ېV2ɜ58fs{>?Ѐơi54V"+y2GZFy)MJSe(u*k`lءPv_!-lxN!G;d lQ%ר] I퐎1" 0(:on~8_]B vDHpzvd̆GQso"ɤ޴*zւ*6Ob[.wЃ\#D˭hiyAB &oS`S 9 ٚ{+.BF9rm0ô<B)/)/%\5\=V\u>"`O.Pcє ha&,ؚEZG.wzPڅl,,Wy7ǚ?d* ˃FӶw4=DɅHKP{'!_$C}P͏*S N qTS?/u 842P"EI7q 3cƩSЬ5iurcFSG}zov= C$m'()AQF_ێ]ˍqTT鎑ϻx')w"4t13~$1#˅JiGKI2zL #A:5Z0 @zT|';mndٿ"0 MfCN*\Z/ccmW[PT:"T$Bd0$/O0fS/@3ؕ7,CMQfTmY jg2)I,S>¹gXv%%B֩^/3RiK;3R>ѱ։u!: &\є+{])וcBqbmu'ΣD)Y$0qcm˿wC9 %!ᕲpX["{{MVLLΙ QxDkEBqԨ4 HR2>dэPm%fYվ΃L`K4MXi㰌!JvD1Wk gsZUG(244f`; 㕘 Y Rќ5uT/ Ʈ>O C㞗)M)ķNEXo- "39_"LI62@GSj]Z0LwM2W.m,{چDySP6jᨒADK~Dr 4*!fP+Pa& k>FM?b>GGe-Hsne+)^*UW 5ϑ2iyqnh+eifLuǙ$cyAup'jlNhE5WdAP sT,G!&ǫ!5=$ OBfl& dw)Yi٬漷̙ Hf!埿12:TˊL'In#U H' >*($LɦQϏxARKЈJܤ: nJN0r%'M!hU!䃵 蠱Y /g1؛=MŶ{x/b=N&,,n=} N9d3pQI2:Zd GOM`qO(6 $Rд<Ru>vqɶQUhVؐR ^>7nFǘBwaC2I:m?cA'eNq)wa쓡 J ;60LQ&,du/O*$TVL9uBQ.5%F9*t 0 *aIA= :~=d\ *JE/C&WDŠ1lTÄ|9OƬ覈B9&>'^u]A:F|px~ }Zh# C hB$dnŽ"_(YU9up-VJzR)͵`o#v*5bIbGS\M=H,2YR'IB{'G{z_~v}A{㰘_.{Bz#M%CUuSfHhpmNf@34fg phwgdMËQ%'(=")m4*#zTM+8`fBYQd^'jvP(`6 5TSbv'!C-q%> Z}06kBsR7 )D)ϢPII] :II%1c0xq)"KxH؊xtYEW+K!%= K2}ǎ@{3hLUfɃȒa>TܤXH+A0GI,H{l1y댛DAFYI(UQr˙ [tJԠfK̇uIf*h@x1d,Fg쪧 EQY$,S32)eB>Jz̕#Pb&伣1)A:O3p~,s+ʪ L!SIDTEѼO8 b-Z&/)$9|kĽ+FjqSEw5DgZU&{PSGȡ1^v*$%,=D~40ѸWWu!iƸ &q.g>޶F/^o!@}G+FNѦ44 &RJܑJ9UfDƛ ^2 @\άٔRaeŅ&Ut c#6~+dheY鴢^{$1c$~K(܍X_c9%n$/18y@M4}4IhĆvh|SzU~A('*0MVcyeRZіD&+@keR`7_T@mG  %aYFcGP;E]}qX׍֐Y3=*5ܨC9ڢ[ÀO>@S@~ jl4iA@(gӀ{E۔c\UeLJ쳠%Ehnq ?;*F1ӆ0XzaP)lx!1QqaXIF8/ihI47-64߷B cX|8קbՈ3pi5H%'8Ng]Xʟ1Ucͅf.tkWnq Zf6ًNPQ*qaKI>ٍi/B!Hu5cۖN Ar4*PYq\vqA94aD앧;~%̧s=pBx\B%.QF[4dz4J6g"iዧBCgmlKW ZBR/ R'Ch%66*R*e Ź YQ]aPXpq: njԲOW?u%JqȖ &XSSC[)z"lXaܕ=#J}m)-;PލJ*ՂSCp??̐Qy9R P@!CːJP^'Vm4ECdt @xG"襆lAvRhe_^֚5ϔS1n܄覝_ lrJ9Hn۸`Rr&^VzLS䗋cg:6⪒N) q)x(t8p<\An$SNjjD|Y(rShtp0j*QG3HB=)Ɇ1*Ӵ'xۙ%ZjXQP )yAwt̒=)0DYAm&F'{I`m Z4~ }Nm$Z0͏OLr.t((d*!SzooALJ-{5Wa#F,I؈g6i1Bj¦=c;bvMҢ&z}\$tn6RQT{u#FDZ׮ВG>?UG%ǘyZ)2=u|)"Zj;M>^ZJsQ9sjicmI%F5rq* %Oa9(WOx6C$_dF reh6IN"1T"JOLjv(J9!t9 U x؟nVnm@$*#2ۙ~CP Q0sIؙ|=r$ <{-"I5e>PN$T 㯐2 E2jߠ9>YB`d5Q{)&Ƨt-OWsY瓍s~H[F<5rXC(FTՌIZi>cQ@KMG$#&@^2tDɹRں"FX 㾒l(82@bFۤMGKsn>h ya`Kl-Jf u$/ )=,@&_'Y* ;(H*jÈ|*tQu]pq ,I"4(>d&drETyu(8 OPC@2'8_A/d@8y91FE63"sd 9SGMY$Mĸ(~ETHU ZSY()+e\w _')Q7?qșn$ A(GegM%NO1CFۿ>B-뷑vs=Crz>/{l7A{V_&}q*D*L<r&;5f;tF!0y<S"1vل Mo%65KP@)]Ek2Q)}}\S_ҞQ$>=OETMU3c qtNn':Y^H㌉FMᰉS ?Lz+$XMmfďQ \!ڄlvQzﲳ '`8v}̒w˦!GEYRoB`?N߃ұIPLvŞ 05tB&)2'56(jRa?dz`ׂRXW%ߓr;kHWohy$`IƓgsa@q2:0p+Igpm+mLvt4iZI QTEV\]-l*cTy?mU)\K.GȺ '2b[Sqέyc8a:%ψ#\ELl͗M+7UCSqt\r29 笵}tjuȏ]mF+ܙfAn 5boNQPr OD'_hG:}8WuϱOW$*lz6g-^8 %dlYuQ"vٱ638UKQd3PpF̔uU ST:HVce!4RjQ||`>|;ORblA*,Km_[ad)FB3>>%3+Fk ȲI NFq4ˊ>4ǫ#(^6JydQ TGx3-UdHc"#P~-:W|r #k$醑c5׈6M=r}`K5Tꁧۂ4Ko~) w^fqE.g$PrK"N$54Rp#TaކhR+">x''  DN͐r+)*ɁCoXyț&lub s0 u,+ c;o1䝱v1!11fy>"Yn%'0W)uuKsȽTj ,Pg!RL2=r9ڌPԬp+GJ⽀-C*\lqRp JbtZ)viI zoԄ'FЩ/&4]G+ǧbf<9<1R6UX*5k#ЮɢydTHOTG>UJy\|VF3@ 'D2?-Ծw)Ku>=U#|dD 3+N6d:܂xI2'k׶4bKBmEIC,|źŷgZFsUn%s2p2rP#Z8|iSdjU-e)JcHp LN0($^Rhc(QWSnu%DOj#*qr)O+e=7hX> BxFK'v`}1* zMHfn?ZU ȩo_Qؘ^ąњ(v@kMQ2sX㢥Q!;& $SQ q@J͏#z6TOFXPd`h߇d" |f%bC)$ g"F4d"\LyPbǡLG{e:1݅44 ?!3(pZ+DbP|(hl6f i|=W;KhAӅ pRnL)آnRhac(PROFcHD}xh c|%P{+judH.3@:#% *~W2גd!jSm!UG"Oy*v~q<Sl2׹Pi(M0ڱ ~<|a$~\NQ\>BR 9'S%` 9d$5~CHDK$)W i*r2W4`#Tdz>68NXO 2eG ΥHvb4m#Fhc( VjD5VRIړ SLt}aRE*VCn`w;Zڜ<@Z hjЮ@n9ZT@#g-נD|c7I"}JLx0Y$>6a2 NlJ I>N/2&%I\\_xv=E=O,O& pgK)4Rc-<g.{?-쁢G`(;q#*tJЎ"rLrt@bJ ؚs#(/W_R+K*e*,ԉT fQ(ȧ/WZOزك~G05\;Tkp89ӷ1Àť!V脙;g ]L#3+17bxl!4yԛTtO)u<`3b3^^vSJǡ875†:5 2G.ˮlJ̹L[kG[Ý\'\'\%6>7< p/^$({^2<>EU'ҸRGa-Rv{K3=HвSyTjt՟j.jh-;@QϗBj2\Uh!"V*ME,8(Y J8,Tه9=U/LL!Ӑ;rEsLȗUFoft}:Q ,24I'Tu73ZsYbҕɘQ9 KPõ)|W)P>$݊&LkOĪQv +ҌBgKX 2[Bö]G'O'h-l]; yrLvqTYHJk>58 Ę$Aj@1%|`&Ru^eZgI+4E%;$ íX 'i̜?)11 +ȽhĖo>@P4SVz xxpthX)ɧ\+6CqN${(4=BCEddd҅-1TRv\SsőtyQva=et=Ӟn&0b^kJz7 D:(!24I#43?|lz!U(h;rSzvH/4fFQc=ĂyrL?^1Ȉ cȷSxK1@@eb#s,"i)̏ #ĖH$f/x~:$r J`e"DdN$=xI*@TgHe%݂ʼn' UAmށOXz'JZW kb>P75Q{#{c [BTK8`fiRz nWVb[6zc҅KeZD pJo_ iġOYɇ)+Ӛ࢐Ok.DΫ*`,O[MKfO1#&Һc.O9s%t+ J`%fnYvJOK~[,WCL<'g8u0{ШHA+3f)i SMG[̒ÌN& z pS-3 ~IA|҆`#qc#k{Qau t*z~ +pUX1 "vK.S ݚ?,q]7s,0 Z<S&YK!GSKuA!OA"O$+\kčcÒ$CLOMjbjD(Dh-Fqe4<ٞ)Y}Fň+Rp,VU>5&ژ>L?',t~*=g$BL=ʖp` x;:kd(w?>Yt>6v'`8'5:G(uE'~))Edpl;x+F GOg-LjP^$ uuJkFzV0 +T'sNA pi}ePL)*q1O?"ʙUQUfHar9@hӲQ1di(yjlL/K:O&?NeL?͐JOM7Z~=8M`?V9 _1M䪞kr0ƁˤmC=Tl\lGRg3oǔZ'#G^hh(6I9Bc^ϮkHm{'g<T R=Ib amS O oXLt \#LSp,iYD:!kmVPf] b7$IDtBNT@(J bI(++rLC4`IdG,jl#{Hbc`/^w Ǥ ]J6荎Vָ:Ӗ^Q~b|aWRHXY,AF$n+0TnB8n(ӑI!a9`|yӨIyM$˷du+)6t-\mI hǕbI!,vYEBtDNˠٙ%7 9b wϡz/r)rωʓ~ƴGFri:&U%A^ 裇'Ik^^I~'̉ǔ 4e_>_O= hv#EH<88M7d'p$J?Ζ vPK_:}%k2M-dXLSھ)7 3;n!gs7>Z2-cI = *4= ) Eat  6^u3oOE)QfgFxG2'&$'WGȑ#O=A \:, WGnSv;Qo@g6n@ E ڃj kzBBU9$痨;Hߪ{>,Tk AG:p}y39"u) Awns@xY]F#i뎺@]JӖnC5W^ ?w)C 2#TI\dgRFgO\'\A `qN%tC MBPx Q 'ǟT Ra&tO\!'6t .;e'FFI66OS}lDB"O$0PO:uJ͌i&3/"$S\sObQZ;jTS\r"R; I 2G).[c㱑<̛ޢS"B]_fg|\2`S*rOtb(gS'؞O :EqؒFʍF/@Q"!̺8> v@,$7Z|JDK0hޟ#؋hdћ''fDM/&=#+C"ȒʈB]FP|_A$ɠ[qɇ@!zfe"xLbOX}GiH= 1`A|Qyث P[J*zvr]΄'3iBrvj_Bo{`z;$ȍQvUd2:6>|ǯGOu,?|)OҨ(us@!;ZGl=* KlB o|tDULEȄ \ aZeM!(A-;ΐ)D G$؃&g ͸$(Ll}Q bBbM rQ"X=2FDѪ93"nQ%8L1:j;%vB=Ilo|_햄O` l h|#@I+و]Rf0KN WMhkL Rz)]YJ,t 9* GeL`9aߧ| <HJ? F?dfC6(\WpQrE"Th,psz~ )š~F2kc C|2bg ^ώؑc edIN>[٣۰qM;. 0q!ƌCSkRIu[}Du;=j'FIB* Bm'KqCh&@jL5iZNʨU_"W2 >r}JEeQF6b=q\35Ғۗ;?q&))*b@c (HlT2"?"#١'D&DMDdAYkl~|M=ʕ]g*NV{~"uY$*,q IHwͮ7BG-8{3rA5Mϳ& mvvRN$*qSg\ %\:ҊPvd6{):AȀ,vO zD&OhY z?JB K2l:FUvE=37hY΋ͰO;m녉~Kuꀂ7EbYu"H7<!T3NtyS4"leb+;J;9u;U$Py+)wj4! 0L`G-Q5oUfϩrzAk'[wzƊQH5~ l]b*-F~0 (u3,idm(BeT UǾ8Iuzⳕ$)tO_c_BnC!Zr[6G 跠Ap?@Nc}ol)gMO?Bo3jqu?@idfNKvNȝrզ/F2]9 >з: JP*P nTzo2 j(D^1Hv_EMT.[Bi:+D$ hGW֐/sZ P`uE%!}B֌SnNIfRN??)feI{LoP!dr1[D|0٭; /xݸü~d[4<눚EqXp ÍcewaROU5%sF:2<@ Δ٧[㙼퐄٣!b@ɂ!zliN } %^tO$(~t= ҃@.j5A,TwLO}*C?jNͿ!Sԥ46woOE#c[Iif)rgA}'mSV^=frJ ŪN`~Յ62 cQgYSfХ6L:m2 QmLtXIE8 &NF|ʇZ1ɛĩ3Vk0#'QD,)6!񓍐hM ?R_eWd*s>\U)NğL6H>vT!ILMl\'c=C{g*?W}$8\/v/ٙϲ>բk~Z'gPrtR2bthG^L=жv)ؑ@R6Sj.B#I@_p9!詮z-|۵7mtUԳ :FRA:bM|/L ^F}Cظ T"Q+oG0zFEU$̥IB`Kdt4GǖIFdI/9ULpicأU\ҎE#dv#|;$ #v2_(zP'{R#v%q4L9;"HbH(1P[0gwCfv >l\#*@r_3e(tIQ6]>Mqr4cu^w(JHn{t;+-oh#0a@D*I&ODwd>4ianecNy?/TQJh[C&gB.O.p7jΝpXK]ey?`YpYeAڭ1 fQfT={'@9OiV'X|[*_\چOc(F<-=7&^Zќ I>}v5Np_D{ V>% tC>vOrG[>⍒D'i;}IhDW$hOR~>T"`!'lPB!ғ/oSB7h#  `30 '{;I"dBTDV֚ },ebw@&'ӗ{Gٯ`R%⟶4~ΖVǖ,.Uz#ނgt|PiƅK׀RT_EpԝUhZ82"M92qr9'*qN`I9%Bvf#2>}u(Y})`t4sܤ8;(xR:0n!lIFzB4=D 5vSe@s4zm:FnpnBE ˛Pd gGciJ)vufB%^^J\M% OZy%`&wm6\v'5m"KH068OM2 ݘOD@ LBO<#G[,MÝ#L"(\RSɮ (k=*LJ8P*! {3='@LL#`xP+}ɞ`l!р'+NOn:I SdtADҿ;M}+#ٿcͬzʲbL|!(A867f#oq&`}tCP:/쟭u3hGBfdۭM;U-YQNI#_Tլ°Ax?7up 犊yWM#\$o42_6عo[ʮ6l;Riϛ3C1m.9 ||3NҌG7] $w 1ZJ8X!p(KؐvEjlh;pQI _뾂 hz+3bBZ_jvx~;4f7Fv *N4e>!Σ1RX}_!ɮMt;5PI \<RE'ӄk:6;iCk H>+M$\#%dRCsw3?)=FVdcxrgDj,uhoŪ#D!eiiuwTP˾$N y4mXmd)S4eAӳG0+TҌ燅xAƃD{?vf3Svbeq:`rFF\`g% ]p]vOٰgLqI^h u/RwOy+R8>ҖI0m= sAO|rJh # tƹ2,jo&AVuǠTasOc-pV~>^|!'lA#|C$k C @,xN=a-f5d[.N?$܇I51CzH粎j7QCpbgN>}rho|CQ|ehZݸd_;*z -mt # CN0a˩%>w1*QuJH%q4&l64J|L1=V=% T'ɨKrt)"iv D A8-W^E;TPS-CV= X˺͊ S"?*Y'DFdS<%A&A,Q?gQ Ǐ#:ZltA Oo _ f癝d-sN5fHDvHdB $bA4BG6O|#ApPGVRܧ&pKvC܍ܖ~ݗAQObU]Fꂞڝ}r2Bo[FhR]M$a}e#t%+TPj)YjP0ܱd{*-A;AMڠhRp1E$2\s#N:JLGLN`I݁P'&bҌx V, a)ԦKx@} {H;Zez hsæ%i#$iu2'9 yoC L觲/UxN@<8`C"zG9[vn$c?*3+OѲhLo{88ʇD;>AҍDp qxABBJ0$$zk1:h)dRXꈓ̛-uG=JvzGԫl|H~ _\Ohq^LA@)>1M>dMnd^F\Q(eT451<.y5$&9VdzT>睁6kG`(E 6u $4q⠴U8)Hy%CO@L[ǻc~?{vC4 Z?/Fʨ )  "Qy2)_,|o$o#"EgǤ`rk-F\ CC涽=I\S읕kT5潒G&w{Sn†|Sz cS]Ɣp`*5MG?REvO`Bl*)t:CUu*,WE4iS&Mq\(,v?M=Uv oz SCǵLQP)1SGfIΧ!ORW>建!f0(Î7lG8B Ҋk}Mv[| xNc$׮]1-m@ N:D偙;S|'YA\bV$߅ϒpq"5%/`,peFr8[dm <'AN:>i0e% QMpH/ڬRJv(3; ;rl&GAnRW(3eFppKI74͢@4]ƒ;YDhFE1YG}U "&g(-'D$}BF-R),u0dF6S54Bԇ* rrra7 aX5뮹b;PvAߤ\f!<ľ2q(G#u2&I9` zoe5t <{&{Rw >Ï[ٜ*x~ NeK$۹ms+^DU-&A1FML!$SZWbcGnՊ/@"efIP4 Yck-$<`}(C{ :qN:{GD:4^&f/о& oolI<`u8K&UB;d+!xT2iˆNEDJ}`dM^vyd(9 l:O%]$MTl  הSOyٓ.(2%l7bs6z,u*x2+ӊ B8ۢ,.pET}{{֭bY)4N8p pdr;C>U)dLhS2^Ż(<F4㈔^A6=)1{_^Y$=&ղI9HGR ;kE%H RXI< ҆N'ۀاoaN1KaA_`/~վ?8HmC2j 8rOY?`ч1ǐ_IRr ʏJ +Z9HUjP;@G3̙^taaG7Nʍ S|!1aUpx BP1EF}r -*Jq{ָ f˪ Ff2oWiW*t!YczEFuz 8,RT%;F~Bm%E_I?p[5-VdkU/!ۋ6!#"KLJF_]zQSn ~N#0ydFLW6 *) \O m*bFOI>7HЗɝp<ձ$D=AǶ8L%  qt8 ƓD75˰hFєm9-rN?Q:FM H%As#BPR3PBs['{]qd(+'w=0( :3=O Lr(;"5[;qMXJY :SF2u'N851sZyX΢iyZ7#ɥYEGfmNr'Kb(>`WoƝ{悫xiԫ83j9v|0!FCN1`Jʑi=W|#\ߢ8F=p(|/? ޽ʣ&"(WbyU)>qCǁ܃a Mؑ}AfۀQړ3$!h*>Hou(=ct9?4;9UPǖ${?}'Ȓlz3I eV-ٱ1hJc늪F y}>[̙@;=Ƚ_dOę BbjbΧ ld< :1H$k:4xM MbV,3i:R;Q АzQ!I][$c-M 7R$؄.Ku =L3**}'oEW|* 땙I~+<u;lta; 3N< 7^i9pdl)W*L%ik$}xGֹk+RlL-FH͔59a6ɜ:)]OO [W#Z#IiQMG.:. "M<͌@YWiV$ LOAx+<< JDO&Dj˸A!MUH X3uDq(z6TL݊q} J8_JƏ\Juq5 yn$8$N8$|O_ ܣ\' @6@ܩ/҈N!gFݨHipeu:޸?@4}plsִA?¼)G:p\(4d,~Mm]6Ϯjܬ~HQ mJRQr:=vqv)cآT7Mx'* UA8F2cXB/(!v*N(ϓNv5aoI)4?}p(W$Sq$T<=62fUT1A2곜Ͳk F(:(]poC>9f= f=oeD3ȣT@[|T'MO>CۃW]+wOx]\# \#_~7{6k2H>6_{'Iy1.`px؋Bp:5!@DqBKm) \4b8 :+Kp^W': 3?}dI 6RkOE,s!!@d7?狅QPUAu 6KNF R~rR ! h;҄O/y 8VI<:ǵ Oo@랸G7}|ɪ Ǐ e$cce'||Dq*Ȏ8 yk޹8=s[9<O5h}qdb!Y'Ӆt:9pe.8F+2?@LPC K@KҦCk>ky/&L@֫l6yJwt=JL&$p -Qxo 6G BВ $v Ta΄Б;$) A!66˳m2 8.,G]s?UI;cFgb-Ss/qλȺ(qC2 'F-6'F> Ů+c8]-²#z湽{;:$$4OI<2w|9s>+= 𧲛4||2O^p Qiױ$%u ;%Itҟ !|E#2_ƙ>v'CM| =pthDsCZ?葵8&'S0.;.TJ̞;hi%0jIN&·Δ*s6<](,xxh8YO?֓s'9]?R99=ʝk@zl]o^Wޏ ǞT~5%u7;9o7o9φK&>d_ SE;تE8.`+>]s9<ƾH$G|DTR|jA*.RS/K͐IԘRq]|~J apJ5fIѾݎ[ HМ JygzZ#` &çe#} `'1\P)e"L#Ez$68N[|L3o8N :<=pO76O?l<|@Ѧ6Tp/@ɮeעL3^4 6g1CDуPUuy6l,('v(IIJ> VO`_dJ4.G6WM=yo:o`u1D<@G FX k@w=N= JC4>H4R1y ه<4rT$#lre喅o#*a~?dsn -vg;m[\|]k-ziF>=͸SA^|[\dhcHpp{( $l1w z" & NOCǣJgv񱣈IB@F)Мv⍂}G}PP$>zW>TC{lK|)Çco>e&|r'_>Gz7\5zfl0$D9JN{%/C|DM&Zr~"#R ϭ[0$/9!j7`Z?e^%6~q0ڎGxE|Mh.6:4$/1Q6QV`i\_|p<#| q@3!5@ c旅 OfEwDv0X{YQe.JJ[sO!BT/@z;}lO/$8 S ❝ga6Iss<HCšpsmcbseʟHx02UQ;v̛76iG^u@9d,`|dþ&9|Z0"= q_ד <ȇ\3lP43@8Q \ֆò]F [3ẓ)0Ʊhlp C*z!/%]G P@Ey $I1d_:(VH5o5o{#|fe p[SЄ^]m49:sZ4G?ֽc_\?4pe0 ‹|Dߏ p2o9S ({)Dlip̎0~z̟*w7쑮kנ>3ɍ;z˗rUAp.ʎRx@x[C=pƕKʟtxξ:nf~Dض:!Wj8[c˜{%GAܦo rpK:8Qx= 'Mp(UJ/IՑ #cG5hzp :'\ђF?)$`c1r[X!F_y3/SϓHeq1 k^xMp/GG5\/., ǟ ;s711lT\-(-ݨlB@M fmg!t(L_7|w|y6yZ;|RQ8N):'\.@_dN*PIz%b[dii`נ8G?Zdz湯g5]s[Od{'vHbɋH$*hPGO?'DT$#/<-P Z%̴7{[:_^0WAx9| S?#sZ잀a@> ix؅DJrC#4('Av*T qd4x%$KV$fJ6ObMe1E\pp }|x9޹5Fo sZˆ3^4e?AdnE`NYCL|xBx tolk8ʚe)3?Goqpr r HD,I `^exO(9bԂ\߱'߽ '"v$'j}* E] Ji/߅&3_RxSc^š끵yƏ;星7Cg?'z=j:&t;$ib4t\}MgN^5}{#Duˆn 5;<'@6q>m\Iac6c\S8O <*Ouf巜Upơ'.@׉w-W5JXhUA։o$MKB B~91<:@HaǷxY!:p>!1AQ"a2qB#Rb 3rC$Sc?,5'9[Uti~0`:383k*u;+'*8xyk?dב0) j$=d4˩@' U~OM=񲩚#>kMĄEi"v?›IH;)p"!#`ys'2Q 3LSfn%7"cAq,uޓd:n f}=3_@ pJ`&6KjtƝX䋪|'贡Bk$GaQ5@Ѓ*iyz",H?mR#I'}7+i0B*q Hi<$uꤴ(9.!/1z!qnJ(X lfdsOo;BoDllOh c9ё6(GhA{q~6LQZlsEB 1[NvBf%=83;`E"3d[uj;UNQrSNc&,7NP0:Bg #!8y;=&SYٝX7M I"z O'^["}[jL@1 L3l-V$b,OCLm7^i+%״zpK|/.EQ$.Ch lZ -ƛ$oF{y"ǃT *H8*&S+1eLtVAwM.y):FQU&!2@Qt_ЩlKz`37D0h(HR'o$CDiIiSShwdXI_2zZ1 p(zsfk=Gf;6?fHF]0閳oɚ//xS>i#X->^ p=suiVKb!5^v)cꋎKlM_8/;Zk[/#{!|Q4k EawicdtH `2Gl)sZ ZBcH%L$[ #&ݓmp{0&?eDV>HI석n';BYP֑ΜRQc/t'f| p'xFDO\F /ǎ7t^e(WqdZ<'Hl6;xF 8(>LB$ CN6*uC wYF `@:_=G1u 9UT .%M>+"A5lVAa8S1jx)`p .Y$pp|?I( ȅ 1J{=@( Lo۔lB-sLNVG?4ELtOe)kj/0^6DqcB{t}Jci@tЇoN$4\C#RޢZߣȴ'dm0/~Eښl]!:_FFOQuc"5 DLVGOi=nihɍ{'D@͕Ql Z]?&_1 oWV>UB0=PtؼR2P,QVZ- IHp#ȭՆ;-CQPM. qS DŽ"pk@[Oa"S:L"8)$gt6@a4_@\VN /k#3i ]ueo%a`&ISEd5st{&s|@Q[H-3} 2:mTLGCDH sk- \GK|#t8b&2ħ AgYN1)Ii dT=S7;ěai-snd^mPaMDsA%T 7 uRIlk9eI0gPLh`CGd" Yetf 6n9Bls x-H"g%LIjq xCX sCFĉN!"}Uern,q=;݂㋠Y--)ں~麟3d`DFY;Y:5 "L"J8 M}Ò޶ʓ$Os{nT%0U rYily$ iW"T0D i^i-`J3j;?xc6qE{2d^ZLH9tqOx6&'>H rFet\Hr`Y(۪ ! ԋP5prj`/;s{BlFܡex\@~(u W!YeQ}iQ`[s(! ,כS(6@{P[DNiZxNu$tx<2ָȞ A8dfɤWLyL& `hceHZweUpp"6G5 ¤4ħQH#o+v8~8s@<|MX7Ft#NJ'F=hF9ѱApC /;vFiuz8&mcFm T5 RNɥ {Ç,8Zֳt2 ٩?D7potdRcǪp wADŚd.Dj6]M7SXbl'=A XS~TuDS2-BZUM*o俩g@e4'{K.y(HM-)w1ȃ1Ͱ(WT;"2V̠Jh!{@F]6a B tv@W'+gpizp0Pa k>ܧRPd[d-E֯Pu6T]ku6J7ޮG˾Ü3B~]bzI|'5F4ZfQlvDo=\<3 OL ^"SAnf `,:Z>FOus(y*@XMMM1 Pc YY" /DqdV%K@ WvVlHl sOO},o I(-xtnp}}ԁfې9l :miyMF>h0a&MփIJkFL(f+Pkh@BFBa8=)F;? Q'bfrSN Wd{ DtdGK%i&#|@썀ix5Z uNiIr nHt^s#sѣUϓ A'Ici5Xf7 QPR[lܢ^^9Ob)r$EVEm.SVPA<"tl2OAv],*LY7tNYc" -bl}@ؠ:"R KSB_H)| ~4;#K槻0xOfcu>͋G'xNJm 34 G )1>>NJvoXN! B3y&? .t]{ ESK[U]8ˆJ(_u$UP,mpi3nz!ӟd/2BTCdY{8A4.d]Ss@=tvM%~#DȊĝL79UD8ddBJZ~=e֛y1qʹaInS&OӨ'& Jj#jStId}akD y MB-tʞ5 {tp韬"Y/9j߄DlPuUNNgk#p "{)BuHN7[rbs䊸$Dtd̍ȢR:eQ%6L`J;8Cj](N8H7ƮW$l@SD͢j8Rd'59/a53IFlZs`msCc=ܑSZ=_T  m*1 "bUiF|!N[EdB 0`ϒp}8@9Q#(~ #Ec}NKzEo4 }㣤A ~҅kg!KO{ ?Q \S_"KDHDۋ"AdQ{ @T oZ^E:I?u {M3(lKSSt81){Uxw,Q$O|m>!$mlښ~:.ʗpm i/Tm767%5'DBȉP|NBEPhMuk]8:D,bG*͊9 %eca(Q Hٺ(Α=UL,=Hsj&BGHB&&?e2GLn9Y F:|)3&VWS0dBvH#@]o>M֣GfonPc>E &L<`Lp|p&''|M.p,Eg迨wa`okt#fr^-;9 ZOq{HJn9k2?&jtgBO; ұ~hQ!Sz2[lʚLX.7~EO&zMlyhq^\?"ȟ 6ADd'2I ѱ A 21DŽ& حG%T<%j"6A-D"Sb[ *۔`I|#2{[wD5RE0$OKF2J:mAE推4{&TeGkRCIi,Ah)U0ՊL@<YђT-bcw@M% Ӊb4w(tlx [IpS=y1=|?ȉ4 6Bei0齄WR\ȣf@5hX.__8 ?H.FY3S]ڟm.vA"GKBi~|et7k/uXxO34 #eE]hB$9l2TrN="O"d&Q=H;#pOwt0d-w/Tm@9;4yDYyAi; Z}SۅHn %n&T2@ Xeɺ>r-V>H2FiX< W;Ҍ%D"[IcOAq Fw y'n[zA$iGF$_t\,l޸d`51 Nxuuy'B,~HZگ#'=U#OŲ ˒Gd`Ueumr捓- pۧgF*('Dr$E( tE(Ph/DKR b Α68Buթ[Cp@B> y ې~ آhB#so|,<"$|o ֙A5ʼ-&֓#H]^RJh 5W}/(hMH8Bc VX^.iLBO:z=S/gqGq o(t&(>OIت6@];0 *'{'U ;;'_6#:~!~0m(~Iv9C oRL8*pWU;زAyqZ>[,HPMFO^I5HUx OXJ.6]2dbS:&,$d7t=Q$ۃtBnt(9yE3{ꌄ B$8_)h6ܧ5~y(vBx@jZv8.fKz'JifFA).ucy"ʅ@IhNa[ oN<7Єtffe=^~17hi,qURPmM' -7XOmL2ye6pvPd3Ҝ'1ֳ\>k+F>D@ #uS4Og 4|H CSFI=%쌁b=ȃ(mr77i%ej7 {CUL̡[H^x3RƩ?A}(;u&b Ӏ/\ZOdQ@1 7ițvo}h6(A HEEd%PQy>J( m5i虲hr.P<S$ SaN>hnV h$d;CSչA֔- '_@\}8bWAvPp3)M4]9mP>$t{A h1{ÇiGIpe85wNdgML9]Q7$}iԼʍf5;Eu?%C-t UL\d-M169WhtnӪhh(Qx bI+3UNd{uHG)5"Q&@t0@{t64T6( LxL֐XKErn lSls|-93I2y :ZėFI"@<'6U9d]".r 0ЪBTuvO*8m+m( KzbN0OusN4ʻmؿta0֞ {%1Q_9AߢxK @ 9oPɹ;"8͡jPOI-&P숨 ^WlB |@FBn>wECUauBl|J(Hi h.{A䆞`'ci xZ`; .<ч|@6jĢ66ŖwԗpFAA?T7<'0U Q*&1%P#PTA!2uVl*44>i;TYHoQ SJdZIdXAĩ'6DLB{DEYC4ns»Ҝϊ$-mVM1!\rk]T՜*t5#n 8Gc1m-W.*>Yʻ˛dZwSq9>hƷ4CqSz U38@M@Im`j<`/D|==uINvMi<_ԨqpB2Ej S]#!v;\a {F XJ.'i.1Ftn@Nt a .1nbqT{'C陵h u DVÈ~$gjs].R,%_Pb"xMߨd[E.HëuCI3MZmtj7Se7T$:r-/ 8p""ai5Ψ@8tK D.D6 I晋76#i@ޡa~Qsn80OIr}-òԘ"  Mr+]ȶZ";~~nh% M9`./yb |!tx.4a T,8Qe;Ԓ r{& V'G=dcHL737 0Pv đ ϼAoZ'8;.;`I lZEeXZdhO,eAj恪64gF 6}zn@Ps t@}wR = oS22vM Q$4ǒt2聶W_} cp98bN!RۄaT-\ ='$y^7b, IPQ={ N Nw(>hAbQTxMkg_g59Il<984u4I?4L<"[u- Ք-OP}""*'ji]#L&?P5I,q.rpwl։$ٱ#As%Y[EoͰm*T[?"tmͿtd'茎 ɠ6'䃞r $x̄^xBcJKmEp Hւ:uwET_Vl[h#*58 % 'uLn67Zx7(dQ-TA- D J5u'SL\$~T D-M<)鈹NuD6(xm#&c0AFDȹOM.tjuѩ>wMcNh+S;M"hI5}T] .9_;bKtm87:; G)`3%;̬Oղ=v0P@%&iU2},VTQ*AoF`&"5@4+0rQ(Hێ728N9k$IwM-' z4vPk'2s䃵اu f}*d ji胒^{*$ֆAbٞ-@*4`m/i6Kj/meզ!D$Y2T9B{(-za6Ok<Ѧ\y2spP"-ichY0:}!Lj;VF s i\0hAŜ1uT^gu")cV5"9SSne¨6)cMsgFc 0e=ԊsAA#o|햓iA'i鳻EkR[WWKIB4 M1;'Tj(vMuGPtqmV# 즋dnu`8j<4$4:|숨mEAɭy== 1p!l-  ji'|['X&q G5"0i}B6*K[$R<Ӵz'鹢U4bA;6CE亡ntZpe4>aQdI视9ADI;o'1V%& `#f8wA ߔҋtǢaӁZ S@ȶ6 RQlt´bPQ8Nܭ<"i9؂9{}-慍#J}7w*YߩЇKFh8Zxx!&=NmBd 1t[H4p<&2G;섛ȠZC?.:y"8M 8TǸ12 EH^:HG^[HB1Uq6<|.ZŠr:qi9eokATȸQ 7|C Zٛ8 #dH#93?548)oW# [H']S9;'̝e57%1.EMk= [K}L8gl@i3Tu[ 7':Cn$޲o uCŢaRƘ({:t`f -9KNe;PM`$#ѹvO `e<ɴN!41I  q! KTç ~L|MNeDtj8v }"Q7PKk 3ġ^vEh3"Ey.IDÈʣSLRWlmdN= (0򣽑W'!jI[U}X.ps7Z{Rw2`Z`ҜKqS`ۘM5`q?l1M,4%zNФ<؈@#pӏ˄' &fm>VuXEi Asu@AvWuQp kEA ʙ8N&ta5X\rZ:`'zxVssNpsqTMѽYX%^>hCQZ@gòM{Zn$ݶ3Pe yͮ5PsVwQM]THB Jp`8>ZLu<7=hICJuAgeb)-*Ad3 aiTs&pQDPI0 nfJH;R &mʧ݆y ],$ UnSs{M`ͮ ܧ<`9\8_vD)Ǫ r&av(8VXnQ + 0(,I1_E!ՐFtcdpxEְQ]qF&QeED )di V;b~<$PAZ]RNx ~,Tk7=֣i8*&Dͺqe.\pA?&g7TIcej:&:ཤvKL-uS^(p2aQl›w(A.#4lQj+14gs[[I&h(4">(t¡ڍsH4.S@m@فiH= 1doO0ٲ +X2";YpH?OQiL26@$[Fk@L}-$@E&:@Z^PuH ^A6|Dy t4;.*!8_ԦȲ N!ZlvN6$j9 tq{/Ps p=Kڗ\[7N5!mnsM-tpEXyb >6G0G.$`'TeN{su\" wN 3hCXq6 yH8Qեk-0 Jy`kU SAiu9UpP apS'=ݦTz CŅGHl&4><&tSOo/iqy&Z  O dM2`r";P.7ZOO!M8B@U|d`###9$(YgMm7D0F '- 9pQ=`]Zd!ױ*M0h&Ht35Q? QPw^Td&XI)xE=4 ir2?Q (=(xqN.N赎܂N&%? -iu7x2!aA8(7rm,f$vCY FusP=`Dh,0$o$/Lo j T^s`D 6#HqT.(2:TxǢQ֡yYC[tDCՄp@@j^toQ@kY%7&aN1tDBt |< dSH&SuAHS d9ZUqZ[l,8;|40,n#ꋞAD=A-=GSy ,k Bq($MB~KDNZ/ !c(ðr꓀q ja5,2nxlL4@EB A!&c{:oɬp1MMߐǴqW.^EbCmJK#I7@A 73Z~TSA0SDH, P麨j4{܆.#.HE{"70Q{:] FH>6jmZa~Zs 8@ۢ ŕpztbzoǽ8A5,࡮`[aL-2&.E&h)ld7?=nM׀v5DM=4SEm0:7NlFPC~S8^![Lt99Ëw]QXk&CSNS_,mP8%N0dmS?"y!_SVݺ6E@B2e0:nSTDxQ9L'`Ё]s}dtĎ`A&dt@wNep!fGX|D_Ȣ8{v9i2SdXI8u2> pOYuH>/ .]s2a7%ЉӨ*涡7lNj.$A_8MPS uB,p֙@A8"4A8H(X8 Șt-9rP%M6,o?eu7 S&KZ}T8'䟠ޓX3wp`sb.PԈˑckN\vUihZu2< 9Yk4uࡨ+`pF..'04Q&A'H$\N{-O!1pi'H@>e^3|{7,Pvt A)fIUwKDc;OhD\[u|$nGYŞ`{"υ[裒0Q?dK!#YDWH$Q=pM0C>q64*ˤ}P.?T&(N+'> M¼9tm{'t,Cm?Zr<-5in*!OC>1w{Vo49S !SPZQ dJdTZ @AS]K-*#( \xӕ;G1H-戝 $0<)l"(&8L&ɒU[$ z""p]QN`uF"~Jm~Kp/9 ('MFDž*tǀϪ"-ImNm-'~2r7^"ZvLxg蝣% '*iPXZ9ا2!tH/@dݤ<S_9j|1zl't@pUQ.ۭ`[]9`5[戉pXpXZ4~ ہ[nT*R"@=ԃ9,\LM/i1,x=, :s2pN8z:~rU'KY6ILGhL"8b<%ijUvEnDyt"#L+K}Q=dG`?stSzen~'2F6M$υt =G`"4UA&CNXvqICNO y#&ҌP #(^\UQ3v]H8F͖0Dq!aOve;Z [IBgFA"TFal#hDs(50NF+;%8C J#̇K[NjPvX@nwS`{] ?@2<&-(3ZyCaᷝNo#t I'Pv]xONI辑hQgY˪6N-hf#df`'NEzXs9uIZ<| ;"˕MgLTlߢnGK-<X[cge 1䠛{@[+@y[l#̀6N8=@h.7t:KFA>HiN4o(ʐӍ^KL Dψq2enۢM mt'54^ҋy;&B 9BmFZ=BuZPݜSCKK^ߢ.hrAuLpp$>Z ]<_W[:o!RO`~<0>ד(j0Sk@]@C]"w@87)^O@cOhv3!\cNL_ LoKDg=Ն{2FRC5x*TһF 7POLJn6*4Q5[,Qh_dKÞ\ͰJodC w53)L# bCȀwOy{EQ`Ȳq1}:x?EKIi`85ˇA6YF$Aph-SG wCM !wSNl=3 N a #!͖g }sUc?DxwJ18N:nm$7s,cF_Ӷmx\DrFcmT`_pkmպv#{[4uZ'I2&k˞yMZn' XK.uˇ;6plP m\{2 p%'j;#zO# [}t 6rCp6M]֓}-"*v{ -p٤w9#0#Yhmid9u;@Z0rk|{%ɼ*X 8LSGMv S$L]oFfb/(mC,W@}s4Vc(j;" NRi 9EkWwN;;.>L|px!ab4Z_p"cu;M-Sۺl:N,dLz@Ǣ&m.:` $7?DoHvV3_Dd 'ƓbM&;#D !tsЃ4^G*9i:37!8kL_Iϋk ;.L4CcD;t5 ӾQ hr #?/>!$7ì7M#Q :3䝡>KE{ry.`;91g({DwC}&%_ԓ4imZG<:G uGKpl6@ r.y(>'+hۂSDS|&ꆖi1T.7DblVC`i8>KO[(gּ@Bރ4 I@\eU%sꀏT'AP^+Btg-t-.. ZͦҀ"2V( с1*к<X~7CL/ Dm4dyƋ W&7fA V4ޖ>ˣ j3|ks"(9ă ^-tB47栎Ad[^D7!4?&sͻ29M0p]ndWnA)F2qL{&tb(qE 0Zy6k#%<5qnTϻUƎGH5fֲk~.Z5[b'wG?ӟC[^u=.#-֠.:+Q2 ,ͤ܎s NA^ѥs`]X%x뤰A~tFmh6{ ӌzDA=&60 $@ycNcAf5yax#>WjѴ`D[9[H!D6|H9n8)3TnpӚM("uvNftHCw9h7X!uE1䎁.H5{/4V WoDxr5h:^ OL-1*{MCMcK:ctۻ_d-E#k {#KAk \i I/pL M@*hA1#ڴ: `Jqp2r.М \(@$rW@]:trr~y!-(yp™FBp/ UpgMi;489J-E= 例NF$7,ZpW1S=!r\.wN |F /wMLGp GAY:zI 6L"ցtQ%n{DH{B*j.i;TV,;*vI/De-JɈ $iՓdZIt]i\w7@=4l!jyPa`h–=9"OcUǑAu mc'!Ft'b)i8E bx=.oXDDg`;mv j8Ko> u#k&xy]!CDmd]kF4OfK1&~ber t4LS|!jtd5)&9FI7 EvU[9생(ӉNlɊKei{ (Os="FrVFQdC%΍:~jXU;Rv@p;+4lNyD] WxU7Hr2V6^"Fw2GPtw6F8d\v/xS}}BH(Fۋ-I@r B?7P0g{ʗA0'xD=@-=2TIyoo <pp@*\LnWmdI ܺ麄si= mtk"wN|mF@:={{d;roL܇dGtF/պi888#uk|pjiZNjCv;+uRP;aTa "ůnwlsZl&-0j>{yYPC4Z6)|vq&jH x=38$j2dбť ^ :$zҀu fnziw~X'Cmx$XdI6/uI|^oʐzW6!jء=78ǒsh%2S871u3 QAp7RNOmF (Bx;eXTp{Ap`~NNGa&m!܏59͑.!az#CʖrSFd&Pɪb5"lk4p^#r.AE& {Fq 8lYE4|qHc#z~Jm+T;y=L{uD5& 0c ͉u{'I10Pl8!b%-pd,^/دArQ0jPsÚ'm(5- ڹ;s@<׉X 4()! di5NUoi0%{4 e D {,f4i:'TC R)]i/zq1&hR|qw*˰Vѽ{/][C&P#"}ϓtSŕVmtN$ '}S7&bE7FK=I_XD^zHZmi7Z,s 9 C) '8"ovNyYO`3<tup<1PIEnAAtzHWFۭ E# #rW{X'=7\ (SF`@aB{꬞YwSLq:c7 C1" "o+?uA#a<2-D+CQ\y"S}S􃭵o7u&YEbѳ\?`߄4ETFyC ivg ر RTAeDbUrZmd! &EXTVWH&A<_M$ '[RxM1m3i{=BHA[]5f3|=j djf0LwOcئ8ԵAa6T6*@R߯;#XeK&uMx{A9 ""!eb=ꤷeAᡦvD"{Qhu`S} uC6(oFϳ ًl!I(W$8@>`!P@A>j5Yd TޣoRG wsʟ/$]#{)-( odFzEEwTYGT0?4Y>-N&h0B፷Dp9Olt^ ]y@h'R&i3UJ-O ˋE8sTfm#q Mբ">aj3PܟGOᘺq{H4CD ֩yd6}vtxӀ6 6' 9DV ȵ'5ä:JrL iw:~8ɔ^Y!_H93 pb`B,ykn[jʭu1&Q N;eZHS=-w߄4Λ7LZӳ8CXi^DN] lmpdS'~TAZy$.&-pe EEl9@Hʈ.1NQ.nL#ωV9د+ vU+",Fne` cۄ,(Ԝq 8JǢAvFiA pl[H0P&-"S .wN. ܠ&*m6x=SRpG_̑ ?\>/pz9@nÙ;'TMQcB uBy#9L7h@^RڑV@ZVwY'*}QX eN 7{+,`#IPoS@e9qj*A֥?E-?5KR~9 B67GR. [M5` cn :nEDAn!Έ:z(TX-đp{"X-FF7*K),@wd[A}?8DE6 %SMΗ5%䙺cb Nv.(ݍ96p3o$!~TIBf<;S,Ҵ z Ay-V?lk-&!͎ M-xNZWN]~UM,GP%vCL]sfl,=].30mt_p* ^P a;FNspA1{(XpNCwD4R߲7#Iud }(AMe@e0 d+!eGenl+ ѶȂ(wG "Yt5  MN`'dZ\يTɭ;vDv; 2jN.uO* PbI.J &lEsIϚp P &ɮ.Dy&ZceA{bE.$t:.h(w(ɵwBda8nc(<4v?ϒ-.NJt|'~4Ll\A DǢp#{E~ls &F ggao;"78bl p{*klSum%5JgMi-KLlPGuyRnWX=V#xE V Ph/, 8T3Q4 }9iNtP|86e5s /sPz|at;l09 J\em F@[J/cN2AH e {"35ǤfB x}W6m^yPGYG#kYjiO\wD=2t-~mBd:~+A@P#DZ +;I`Do8@^+(+ ] NBZɺpUWn@ZDIJ_䩾U )Ջi8ЅS=hV Q_E|"/ŠpvanW{"@ʉi~JlX;y$j vMloa>i'2d韒EEHB` Fy4'utT[x6@dBf1w.ŀtGI]#I1>k9/vE"? qnl@RX@s@P}]q ]Lx ;Z~@{x;_QAf7v5-:0AfE֙h񝐡+&08HL})6B߄C]Fbvs~`&o >M!; ]1`MOjtN;LZI?BrQڏI&HwD:˯Q~M/mxoK7@6] 6iCGX"* SM@T1E 셾T@#|Hlb-dcD@"' E2a$T쇞9fk,Y3ŕvKU_; *TGLfaUS7:]vW.7QV5&7M;! @v<1(G$8:%t}PZ9iiB$'cO8ȸpottȿL 8 8D2-(=BEH=X5HwT1 z}'`y&OP8uC=G(8(벓ZMZyOh O" V0vL jLeBwk2شU|"D{x^Ki Iae[{0lZ n[V({ifNpO]EGiA&EE"dkjÆ0 xvt1vN0hx04".yr*6UjB tb;b~Zi"N.SD][lBkȣhX"'w)ĊN$ߺ+"=٣|3p>H_NPc^I"6x GpPZ H??7d7WN3[T{{ż$M}FJ%߳B1JOtZpw6D1]HOa#8Dd"TKA<-F(y?X4֘T<:,^C(%O)Q}}_8mS/' iWDO1f퍐xL gfʶ4Fc@ ]1wœ]2 5s> es` 2DYAo?UM.:sSCr%5-ⵜb`ɠ|=^{v}tSWrX`ZtȾF@s# wՂ:R][ͪyAkq2桏-! ا@7 Ǻ-tJ邲}BLVf@I2pCE e0n퐸& (XĄ^S¾PꍷEhR PmY; HRJtu +>6vV4'D’6@DJ%V@pm*d>9 Ӂ0~EZFN&8;b>׼{S6 c{&>LR npzzSLlDM38 m9ߌ#䋀AēIZX,z|y# ok.44d88H0 mUA=$uwW`üю89RET9!M:!iyL:b M,tX4P H!!y@ Ģ 3]T\j&l!r]jK)2{0/u6o(4A?UOWR{nђEӋo#? 7=]7 dx(4^ۯ*8靅SE!=we~? /p !4E#E(^^I|qtDnQhw(߲|w:۠ABYNp!p'u % A@+'tRF ׈"*>[t#3yoWc~ D#vnaQe<;PtK_NsH1 A^6;C8zDAt+lAAxVR@TT7j2{9R ۔,T1fJh>T Q U0~>A/hq]B`A1WOߤR!Mx Т6UA{\cMWAh^ "P?vEi gZG/%wCMf@XOy!_DDxܢ XV$y@TL"Ŕ48"Cwa LY?y)ܠOT240tﺗTְDvM6M H:\3h]M'g!1(·*i%B$zY(u%Ġ%N- ]Vd$ZBi}RmL"@E;l\ >ۍȂ Wʡ}x'E9Y@JN !^;(h'V7)7U ^P2CA蘛PiutMrx%Nm%p"':"LnkPNH%nȵ񚂑)bSsg f%4I!HzD,O6n &"!w (4% Gt^ ~\ \x>*꧲XGL (oq 6 y'tE$Biv SKyhZ* E0r6<'Qno4 c2;k(/y0ͮ)n16\^FP.q(3Lk`=n;EJ轠Bsw<(im`%ċ)S{Mx쎡q0 u. XFP"-_ܰGWC+#Jg#(&-AAB@. a#ˋ&#S\gjН{ G5д #f|)T^tlr8(J"9D"=hX( ePrnO 6 (d `Vo|Ͳ9@Pڒѷ)nˉ8q7 !=l;*$p5 F{ n a xC #>J]JMl$A  z!{4 \&2H>.ʦnv*\0O9@DRBʨiz/%Y"z 'ﵚLpDu! YLz8)'(zB0~K=]"X]Us}.cSÜev*m@W+r`/xS3vD H@#hvEd4cvt~X/?{l<4Ɵ06ZNiiq.9EwT[*"'(ItdrPxcPV0CkH+ K}ӥk ^9T9!xB>|8ӿ nAq䲏Xg6oCeB h?p0N7FЊ$nwR9!}=J ٞQ{iSNpwT`>/xnbM{_2,!?Dm"d\UL4|h=&qMT /pokwu_pd%^:!l4ȸMɆu+*ԑ\oޓ\_N6w5 ;ex7 뮦 p2*]Q.GCMT\cNKX(:bm1ta_d@I }ӋyS2rb;L:W@rLlj3N.7 ?tK~J0$gI0cW">xlێQsCJ\dS[d^eGm](#x@Hq#-F&- mdY,*[""yB#ꇞ v% $z!E#TŤD{vYgvNm"yVptPn%9k j@oB-vNrlqmOo0]0s:яEcӝDfp2yh;#Vkq ްd f@>p dHȘ?4ϳBH[GCS5 FcO {/u=U9of;A>FBG}ئ [4z}X]}A%j\[p,fCK]t YhO솋[n7-PQ@DtYJqyDlXd H,`fOTynPtM 9FŖfB%ل9@>|Ѻ臖ʠtX;+qc.$'Hvi(M kHv>I -y>I8Z8S_ Umu Yl;A{md)ה')x/3 Ġ`gt.bީSppGd83WFacmN#ZEXlȱC&6DtL.,Нa`F0du8\fmu6Vp'UKF";"샃tAʳɑő}8n~b<q, {_:~Kys7ةbdjitq{$ipϒR@wĬ+_t{4DŽ`llum( òs^0(M^-ʑ ؔߕFlzl GAwxDYEXn" U0H8]CjTjoX7ax3b8ߩ8467LD9{{[聫c#t[%|4n"'.Ӌl^ ǡDI陰G`CE)8ʤX@ Y^:vN1ëh"i$ ٠s@E`!Cv(1%wm+{$!HꚾGb`Td*m/"="6 #;x8l 0TMi,{fLCtLT-3SrEyvFX3B~9H<#őº"B(m6Du’7NPtJhDDʂrQq!QDv pn$z .Zd/ˆpSm͑&VW'rl4*crS\"Do]"#C.UOt7p<X 2& :84A@͕&A'$*\ڌ*m&Fpd`d$ 4Oϱ.sw0Ik-c߄n]Uȇ[ȦzeŖ[ET;+ej{m0 !*Λ $Y918B#ޟ]I6k2op MQ(gbcBBqh8"'桺oq'^m.{`DdѽnMVً8g9֥c:OZKD+*Р(3>*CvZ#$l7G6@ʢ}ԆPxݐ+G2/@8!'*yQT;cxȈQExRI Z.8²q,4t^Ɓ] 쀲'd^S"e:u==!H ' E!uc_YLx(k#h>?2==X$g6AiAsg{Jup3ӋxA &#Q#TA Wd 1扝x ]dRWĠ C ,!EO 44FlmV'dOy 0#3dA!Cz#u4Θ-| &vrt>AI&hn`USX..&Ppao_WSFE!P9@7yA}U/GWT>}hl!`fP{_+bt ']s HI򁝔1 pps~9Pf[ os̫B;o$n0~Hy >`FQAZOLD+,b'(G UP%0rۄ0>Id%9{ nCE8 69&CEb*SVP-hѹNa5XmBH!7z&wo] ? -{aq ȏT:tk5C"F`w%N-sLY r0-PJ @iMKH'#)4Kt]g~V6=bm p6ERn HY!Hv+븓6l³H8<}djInBt7q;yD8@}pi^ #WP9? Cڛ4wWAyiP26dW|( ;ӶOcpt|"TLA6BHn5DH _✐ N&D"Юcbzy &UvĄl!了D p7hmVDOTn2HAQy^!FtKC]'{unaAU쁤$ZA (XTxM6DPl(I$v uB"WLOX*v/x sQ>䶹gj{AMӼ @8E8P!S:mo"I"~B sYYu"\ P:$ )'ƛORZ;4L81%s)i8ŮF,GEs!;H;1%'7othtꆥ}'tAqBN]'P$Lv뉓9DP1u DE'Dnw1V`;-il7juBr/Hf,Ps\j^&Hdct%#C?ƛ=r#3!Lm6A)|[B4Wj mBcPiGBF9X%M²&~U^//Oa' <nce182׮e8 .(tN-+@'\~7jiܪevPIh0h}c;N' @[lUM$UKIZjD_(Ffȵ#!#}UnLG$ĪL3Qk).u^heE*7@t.؍ӃO؈uMڷ{BrUy4=Zn%eg@LnJV H2H2%a$'t$HlEʳ+tQ NRD0QDFuIa9sl1d`#$iMw'ADsA$;$0 :jl`$Fe1۱4`WXo A5y\ $ Kplkl8U<"CUH:lQ d˙,6.1t0EѼB#<!@qƚCau%i ;h:ctb5*a$,_v  ^[m˥Zc.IWd0`ئ l'i|rQ umHVt"O (z5AτM8Ϛ,khd괿$o`hB[cvSM a?wHvNQP) =npe>%{^I[d[ctŔQYW_bJ|3}aC##tJߚuFRۧN"nT8G-;SZSN\SDZk+7+3S9hnI-&*wĈ?tQZ8N"Y3M '("Gpr$ [#S=;'Rd<,<-RsNduGq"׷c62@a(;'6D/|'Ө @l}2C,ў~k*`6$ dD*aD ,!e(t.EB @HiMHD`Q'9e" ,"d h FfS8Gd|RчYonJ$dgdI'*)VOurV6@NjWݕ 8DTo5?( Iqp0xD p#6AyDUrv P5A4QhgXL072F鮁8AӌbǦP/}LTj1&ls]KDܘBP{H(P 4;pC;WpQL uqr! lLVn).I1 *y@"JD*[%29)sQ6& @~}] Ip'SG*l[`AG9FF( }SȹD1d.JDw $<@},pDP|%9&DxC=GNQ#uTd5ёdk%SHZ=U|\xVdt a4n!88h/]'p^c)@08FFT0y<ןT !, @Xp酤GwvPL58RI&pQǰyPruKZx3 Hʐ؁;n#)j:t !Yyed ZlgJq~bqxBUiFÕP=8)qt#U%E#$F!a*ܬ/ W¸ADD9wG@" 2`*, z 'AunY(  5tt;Js}T~U%5ڮ7hB JNt@^Œ,`{2i*SgTߢ>ۄnYd(҈BP*@-D(WBI "@N ߏ`,±C{B@ӧ#nzX~audo%>. 8  Z@6߅6N|׊4X6DNkC;f#De Vk:F\M ID^%uKOHC! @Qsyex">ht"9ی(6lJWYH+l ,M'7YFPH!Ӻ{syFeo68YN#줝@^J):Qc$ bӺ'ݹG8/D. n͐72M8>$ HyGn(0D6$YMЪ;b|& 2*{cxUix*GPt 7D@v,H B 8D!z`؉ke|B0C+$ ʡw-`qq 4IiuN=!UUAv.0W:O({ w@ﺀ  6V!hpcloqr:TPho87Hn$9bM4g(^/! 섀+?`.=(i7Lh7pWH ڡ.S!![+TnJ1 !L|D<Qt[*8<\ a(sR' H셾vQtM*R'&.&B$愝QF$]ZBLi65e[1P]AUSyDADHJ^u!`=藺5X+"=APvY9C޴DZmlxUiI( O*d]}ʳwF+SRN!4J s-'›}ءkYA,*Q#lP(N6*m}0@ax3 (rLwUsAǒ2nQ 2H_~h6~HF|3H_l"Nۅ"$ed!>]SIIj(%<"؁N.D5pVA3d Wl qʆ2JCdc7{'H"–~HtV!˶T&PJ(vM# 7D]!A t5gt:iM$"Hx"9NF)q1(| *ʭT`N}NvVFee s7acYi]Ad,( }P LgMtXtFQq-:Q>|A=h? [)oHJ9.clT5ϚZ:#>3GEwȟqQi""48Ii' 2rl;d@ffWJm!6 !DZJ `¾;"H%:ް(G$JMӌD#.Oo8.3yjEVW".Na=K$=[&|&wP\bWtڹ~[)sZ{a=EtVm;Fe9}2&D=H)nۢ&97wV|LHn.9했%jU璚m(Na, 2" axBDzc 򨵐f}(_eD~a{+4ĭ¸5хo8R-䳲*=⁖7LU'5$ ^P2kw@uuP5dxI7qp6>0, ?՝G Rv86Z"72HC2WP@O SfB,-ip(^P{OP榢ޓAǂU37R"ҊxjZ%[]~B@3D$'Ico(@&+.]]YXU {L{8auWP,‹fбB&Q#0nNiY${|=ОS,d*J5At!g6@ n>Ewt܋O9c2 (m(R1 ;zt %I# BaS :+C(s}Q8li%6B`Db0cu򃶞0w]9@ +ɁOqLB 4Jr%@{sh R.'"c@G-/V$wFW ,J¼Q- u,rL$4y@N`;"ւOυ9}tH}5 ~>)A!D2oꨟՅNی &D#  >y!C ;l7AIV2怒;TnIB>`hA98Bt.0lf"8%D8Q| 4D< vݹTU2}zgD_u.PI.$#@.1~I:FG*@t g谸u y׺DCJ>sId0"\M(8g'YkKWE]B{$#pkMc`edJ Ye;7Bn&OI"dE$,r˙H2Q"غmpe^`lvb0   G9J뉔`_ IB!¾/d#z:'t8L5w ,{;G &wEt 6d!ETv8AwlU@3n鮢O'nnKY7(HJ\9.~mBs rEmo@xDU1pj5ɷ+( `V \>a.&EBhj5GKY@5ŞH s6p-9@=m~DDD\wEin; xY[~+ec>ʢѕ@* rd -!{/նDZ=i]il 8V@i@܏ lViR㵮d8.$ŶD7N}[g31s, l o! 9όy(3 ^ㅵCJ=Ph{C[zl!xIϒ'M3M{5:d{FwMM9@8Lu V\mMjCͿ?4Y]@,' ϴ9D  Wa !nE.P9k\(A<X,L"GMڭ qXI:8D}|**yuʄ"Ne%9&![bIt$,n=W*@=Ӡ9Etf2`G29RϢ:U$QmF' )`iuS\ {`l w ւe nd?P@%o) FP ahWw *mB8D uDքuI8(6'7[!i c>Hӑy, 3]n*{d!qu(t Zte=>gUU թ'JA̚DD4(W QE5|ӱMW\/Ru~ʫrq'UrHa4%9)Y ={c6%S!=59{SSZ 7U2^[* k)qA(PSw?d e;NcQ2}Q>{nLϠ */Udo¿B#mWQe.qMNkFd˄p9Q}S5Fp\Ws6'hLW!7r[1ubXL_ד]p9)qix.j(QZ;'{-X`X]P2Iod ,sH;)?USP6LUWoOeI1 a nm+ARnVgA8ʐ.L8]MUO1d6M"2G0Ո]Q>HE4țaA;PMD=\d-ѺAu_qȔ2rD At` Kxk)Ҏ#B'i@N\ܹRCjuy—11yLJzIj9 325g%.R7H.m@b/苉&m-9.x4kA#HI9DgdHH-pĚ. I& 4q=|BttI>|q>'tfN y-ӟa3FO°Ya9lm͡^Jt4a\B+D*j3dpO(=;a:fzbc떽GXM%5,Th}t~ Orœƚd&8~/?hg`[dJ|F}7 pҬQ2I!bvXN(T z#s~P$#q~I2 F\J=D[ 'Pʰ+Ō" W&۲Fv]GtH<@ `nfP G7Gb j#<"A;.^VB&!Ƒ }lPna9y`8%TIm3 eaI6,IlEBf!od { sŸw[j,&f7A#9W"au'' Ecus5݃1GP42L0ds1V>;/~-4:?԰tdt~i`:NW.+ߑYSMdåOa6(pOђ\y / *7\l/F/3.Qn$W re ,|CuIwX],d CCZm"MжB iBnP[(7]  Nx9($6蹎u1m^OEȼr $*ZfGe+:͎B)_83.CT6Mӿ]R\Lk q vu8N}?OCgȬ.| ?7AetCY(D~`J fA9C8@s]R{}s^8^% :QYia0~4-赤ˬl{5xLkli/es]%xZ.$L%dstz{ Iv,la9p' ?%bdJ6 Uey[F8aHt>N#ѩ/4?>eZp`"ԼT% y+a8j6N ^ 7Ct Ty64> O[lꎶ-٫v1z;\{qx\/ 2Miu5mSFЙ6(C&{}!LϘLsL՞@P&?Ve GQ|-9jU0&#|BLi"*?~k B1~^R*:ҭ?$&Z$OŶ ]o>HNVŽ6‚:IQ %ݾ$!t-Yd2y F[({T 76_^Pb# zB5X, 24^Q6$Zew"*Y#{.N=F ]Ȇ8jd$Bj$E;ENh|ԖZolrJ%n|:@"P w*: X3B=6Vӱ+DoOҪc:e4Xn$>8Cw@ D!EH)XWtMœND,pku Ů.ǎR+US-ifZBZ#RH6O1/.y^ܸi\HJ{@%;boAai54K7OLstIt^d]\|Dǰ/K &ܢ`DƬ; t!ܠ_̺@{^łoH1XCtNeۓw.mp5E55n](GZQŇ?T.)QNn?T.r->X>Ⱥ-"` 6~蟰SF|gB T.>IhD6AcLnTWEᡤe-qdj ͓u:)$t@.mċ-P $Mˌ"jYI9?eI|xHu }-dT6ByD:L)A-(,dAzEQZe9@-hs` tGAp$Ll1"ĠONcs@uͮp'a1aBQydhcZK|-4ӍRrFatڎ3P{ ;@H{L#P"I隝eVZZr~#5?m-xr u i֨u@{H ׀b?5tV"^h>D̈"ު2SjjkI`$Gp]^#KMCs{MS8Z:OS8CHmQ,+w -nÕ@+hiikgh #i(k[TbY>\wQH 6mb¾*B1±h["CwAʆ'FY } %S6 ˬX'̮֒$ؠ-𬋞wD6A:yj,66Uֈ#UUuI8B2p(~⋠PKM`Q~HnǷW@{YCIJiDN#>ji,?4E&(` 8^J"; сdKEUpk\}YM` Y.ҵE{6ZwU i(m`M6!CH"B y쏼s<= Ӱ(f8(h!wv yY9 hN:f2$NPbUMH1tZo5ĭ f#'Q 0W!"o(%$8U[`)TVrf^/sdXX ӟnѸO//Cd!^䡀; 3l9P ʒ}DHߪ6T ]U8 j5G'NC5wJ7>JlQ3(/[e\}4VNiVvFEgٟeEz }d] _Z4LGH@DC"ܢ`6@ =T˩; (:[..s2B(@In C@}7Q $^hBa܄kiQ+e`hjuI8LyOBpge h?eiM'P>@ Z:>+żH~ȳPS+L̬plQeXD=Lcb,Op 4}7t ~TvCIIحGŜw(Ff# x<$*%{_6f7Euѧ*k "O[&{fIl !M:< *G{'>AE$tl[|<@ꄍ|/7Mc5+{G}s@?4K-"\=c*7/4 ǚ]d;F7CSL!yCKwDlID*EB>j|Rʧ9~_\V5U eOQ(91]mw6/L2¸"̭+\>e}7i]p8ED@niC 6bǀ:O3 '+*S>ly|]D +u`X(G/#2ߚ44a}-p8"m ?$Brk$GЄ ex`#SKNnljEi u:N`߅$ٽCe @s^Bj˸Fb}Q|!z #CNa(>IPѿ(P8^08hI7Ѻ4 Dѷ{oC>A w)L^l./ zt )=UE@}wYP>hD\LtЧ ̡8VdmQ~ZN?KL9wďFkwD] O-siY @Ɍ2>kU>lEc2pEH rjAR! DQ2yE & \Oi`,{oeVO+#`PL{d&IQ/JRZ=Ǩ@{^>KŲ%/[0xx.!lْxH+aA%xGc r_l}W3T\aCA̢mCajk\c'eeA6&KdzBy.ȋ=\].}LtR~ sI?YُDڌ=S*I$7@TIߢf6UX!պM f@P#D4}aI.Ve^\"L)f }7ܠo<(|nU>Qq4R$.(˃SEÅn% ?$ze:`t[H%5/G9F{nLA 4ڛ]e9MC)Xm@FJx2W$]Xi;Ym:E/F6t{wGpeك=e3ka5Ri%{jaٲ7ant\>hWh^@*W@};0QZA(&hh1&<t9n~\ƴo)CNFH@Xs+OU^M(8{  D'`B=4|܁mfd#$eZ=sMBee"YFMn xQ %syU)`qYcu PdMI# 0ܨC9#![lp,& t Bc1rU$rAd}0ks{21^&U#ZgQNmujy[ p  .P!XqevU'su6]>WWebdq.Հ7x!\$ ]yNs3m%8Kf{3%ȃ&d#}D"*ouB줝[op#d[ە[s..D,6rS 4%ܯ$!굅KIְZ,|Yo^}VO .ebW֠ui_\e;^̇`їEـ(찲CNIP7$\[^դ0j3oEkQepUYYY\h!8Y #tSweFmOa@ V),qR<"CJa~Sinoat|2Z-](tXXL,2@6Y5OMQ#g䁓<#[mҞ^}NnH ԟf\m`v(u|ї^7DD!u@J**+@hF~c;'!t榏kQ5wl%[M$`CXMrlan+i鵭$u;> 4$WED,/!b^[ݭ}a ?\!S-YFId^^ ``.e='W[KD-'CuLкf>W켬/k Zp$I6nBdmWrHX8أS1SASP6戦ZE7_D0c3 d;ź NBhx+B耄 Akv.89ewY,Q2Ob3dz&8 6>)#6>)ShD]hioXKR)AuH6F̬찂g{ShD꾧.`]/iQ{ߣN@i _tj`9[(۠KRU NacM79Ap-ϝP mV.0iVfc~S~%0˨W貢~"LHL-3Hq6(/O Yz#koA7?\T + Ajs- 9}-1T~<{{.;Bt$ l9D6I8@=©!bnʭL8Eć61AxÏZq9 BjEU̿Q$@qrE 1<"mt0eR"D}Ђ7u"=P3 UyA#J2XpA0S,LҴnVn!~ˌK Z7ݦ95i4:oU%lQQR ;_BKoC~LՕӝXfOt^d;M`iW_6G+t:mtOZos4LdkbaA'ttɸkE[7RM#`[b6(ti_8yJm秲돚0" ij:'gBJ$?yW!XfV)͹ AL`p<b=V30HVi>%o0 7%L| XGF6i{,mF:5B7qwN*GӺ x5l"!dV>їM_&7 ǶC@t䕩y>iķmѐKPsXoo򤅀V~J(XD=|֬6j0v/.ge_ O~#,/7Osh9Dػ;"C=:o!)-{̯C=`-vO=Ėk{ٝ/Aqe=Z{.#"j0}g6OovGe^VtxmcCXH(MpbD}YS%\nua?ueZO-d@XV fG!zZzZxYB K-Nɓ ȫB7^Cz( SeT1.7h.Ust0\"!+ U}AwP3k{!Rֱ0) wabTӛXe85*ط2]%Ҿ!ižjCrLɲ脸ܭ[ne\!C%AB5t͗6%=h2-粠 vOx:oWB(@e`ϳ oG_Hɣڬŀ?$$7XDVJy9V?(@X Y H<m%fѱ8RDyۄ9Q V睰/@/0kK d};:ocTO {+p?4IC@ψMNi?THoWr5Ё̄qO>ed(N*B=` FPsdGkARr7(;NN {|"μ1ElxZJk=O`!C(WմP7{>&n{ǽ LZ7º6 ڤH6,ق GS[L3VT\fmO2|E{qUфI@g}Vgpe ߄A Huo'OBFJi4ÏȐrL!]qzm Cp7VB[nBBŷN(~ v]^ӰPAu^aG!CmUUr/_$3~Q${ oa[ۅ+ l%R( -G5'HX4k)7tot͕}$\V,q(6Y Į FP=f}p P`>+[BX+B+!u]X{02n}bcu M=۩u^)@xXXQanB#LTPpxFnkv\7`;:MDO{ YDoF |F,/a ̬`c-t d,@YV;\ ]*s'di&#teԯE :ٟe6B}V}Pf>k =Zcp"~أ1 :QkSC<wNm! A Eu#[3YYB!m,fh vA8)ij2l#QO&쿳沰]aS!(e xd@aYOPq9:X+:9Bhʢs^OTK! -7 Y8F%X0a|xP7I<mWtoUlbJ(4. J YY++IJ謬r!C:wW YXi@ڤ=&aA]yO6q$e}& ܶBMdo$p4XH Q hŋz~DGG}#7Z |L[GLUFBX~b#è:Ŋ,YTNlȀěAoܷ!0> ۱O,ƺlDVGlrVjC/05@cE&(䡐1 tNƉ!Bv:'UW5c gR 41LB* d 졫X2z"oɉ>0fxP&f zS |SUPd'PbZO/A A (BJ"YL&A`r=!ra4|&9G1 6˕Z?RM.̭5\9c$R bGʡARRКي=꼖Ts$Xj] V*Q  @60N+ s?(pZ?1]m:+m⠬V+_ f?3L)g}}"扇)$XF3x8s H??<.2 yb%FL3bS1d2`6Șh,HHb ٘h?# tB+B #g[g;37ª3]!EW!8g{€m(pz8tC *PͻQ0iP~!ٕbf!8@x c&ʸdӼ@1X6~ *BEC5Ou:exP-)G$|Fr?%Ѐ#P L`[@&?Q'IŌpyXJ IXxt+@9yr#lSY/F;BP[A5P`XH£pFFCk"hTui$0#u.~w5(0<҇-ȽZ< [EK|FK0^.tb"i@32YO93MJ'b hi\. tB…aj];j hPyA zH|AQ'Ԡaf8p#P/)#IE !Fc>z  9"wv? Wc0]^@DP*8d"`{ M ) =(L^Qܠ4>?k%5bSbĥ"48C\:Q_Lmgh@D= E䏈y&V͉&/31F(W ,K"`j@AdSʂ .msԿMZ#BJ丰TM\Y X8ή@v9LgXQݬ # g˨!h@Yt`p ʞULjpͮss(}<4ӑH py@s*Z_KB \D-[ȎQeDQ$ `]F= !e@Y X"8Ju ׌ B@F>+S~$sq6%x4WCs7iB$8w _Q|Qmf`ީ`VʴS~0GX N5aM2mʏcq5 cp8@Rw9"RG|!rK: t#n42f悞kWz3F'=q@1~HEtt@H/a7d &LB0Hunp $MH/+a=`>"8x;F2vn܀g $UQ$&އˆ_f-9v^{o1`kϴU.nuPIG` ]Uچ/vNPѐhz_zX 4Tq5yX~j-A+)|/B7Jn_~8 _292gD@]yt]5maH 8zoϢ ZI KUDHJH,Y3U=/<bCKg mv,3+BŜ}"--%-1@l>&482 iQ-mx*"mrgXɳpH~%:"2a4Rք Ԫk[Dg1*4 v"<`Vn#B&Ɛ>Yrb [%mKqz8Jh ^^HĕRq wS҂ Dy  D,q#XY9U&[oLdnd(|⧁`EZXlP @B/\qgo[!8k_;"`[B"62b1B]8l_X*+-!2r5w.3s&S#O4g[MC <19"P|鶧|F9 >M̏!Ȋ߶!GbM`0*'d%Q-8Y0FfZy.+ȲdZXA  D ؅fBZoY<[ÕP Dl2F~f1馏v% MR6<|& C[78">a-c8Y'ۀ}X0~!YMmbWBjujP9@FqY / u`(XӗIc$A˙F䯒'g ,-y U<p6KbCBf'=8YH l_2C44yh "p9=&.4c3H{S2j!4ѼD}P9ooy3%4A JE>Sk;` (_P|FrQL Y%Ƿ!h3H/+ GMxƲB>`D0#;92A4l 58 ~ʢ{KKaNFuD7 yu(@cr;iA3 9!)CSRϿ36Aۃ+yrR#4lr{s>?|\ ЇǸH=2 ,w P-u LK`i#FQ@E!Ӥ!ZNdlL ?Jw/Q}1 y~XNGYw  R6a(kQ&.9b0fX _0h6JQHܱ:fy*3&k#'\`Zw5iA3`b`"!γ*i /MX)T0?kY70`2-330EnFki s9p)\`u(\,Kȡ]YAr L>|b" A?{ d,X0uScB>=0J˸$79"M f]Eՠ@[ Pc$z uAgJ%G@kޖXU1w]jN <OA+E!c X+Ch2E=rOQ p[엪l;' Eisbʈ֮?Z0$u r8L~q#1`~+b,@HAV`$o*;b~B5h=D0v?_@爎Ɓ "1 =j3#A|JeLS|&̵C ŃsnyQXHp 3mbim1w }x_jQ'pl>dviebfâ"!ff+- & !c|;FI)<σ\]#3I |L}73|M u=᠙jyhL 1\qʕ psP < ]>gH`ׄM&2 瓆6qL pH/>D!ȋ+PrR0@u/(:d1*O]M mW,Y#wgab8#ľ [4T spptp5 6-|CVA>y]?2ݵ C4y?$^IDau0jθ`EE"'BF˘]lrZ }y+n(!#6T"e8(0xF`/˚F7IZz[QCx0!)摘m i0R;} T{tK tK hu5v#kG.8WqZ:p#ϤCc ;l:ΥfTd=AH,5υ7Å<%ѓX0@O%(2PCCY(%@lMɿy{Q <:i" i }O@eV!hgR@@+r+/N cU6 Q bes03/ };x!~1>fyvVS@rY۳h~cɄ4I%Þ@F!pN Ub0r,Mĝ <* ɚq"xT۸@S.|s `Ajp%P>j;x/gK1̴90KseMa"aw3^ex@#`0,bXcT]nabc 7"L u)D1%cB'P{qIv:.́a&u-C| FBW$Aq+̬ĉd>rUW,CB ]Rül[a@dLH"XVwgaL 0yY NֶU0҈3@Y9 ðKpa,!X>rAҍD^st0{=!=ʉ&zG‡l,XNPbnJ<:b] &$/&~>.r0f'U/GpjޢEʰ,G oKH!v{v(CP!C4= 2q( }`\8ذeM|0EF?a|(*0R0 v#B,clW!3aw"? b(Xoq%F\ XY ($,c2s; #E%2P Uaт9KDKim`9==&.`Q!.\$"*,f YݰA$EGbi+kaZkmϵ~#P=a#cdXyCsK3˦g̻pP[5^D/f#caAA'( 1\&s`D 3(D8ўh̑ -$GshDG I[eS@0dU^2MR@LjGQ gb0Fl!%1u4Jf+5PЬ\{ +i9+*|Spð0Ug1ÊgѮ2n>q[ tG)}C"03x$!<2rvg_s BCeXIIG6RYN=繁-)(fv% $i\uI,81R URoG`G& 9Z l :4[ZqvR]NVhF},~ba]JԱ( d \l߈ך2NPXx0A-ϩ\R&8a ,`w4cVO3 U."ĖpTV1D4IhQ 62Hs+~$?jF u̿:w@!8E<YhEdDwN*70`XV-8n|2as)u@o9=Ge)uafIJp#pr@N kmHabʀb?*^As,P_0 &f 2:9:J90yxeMT;13=LvP&*"C㙚F;hO8LFzaK (q3bޥ/;A/pCыY]K if!}0Gj(2c0Xb2 +G1h*QS2сX!'o /0-cb H `H,X`-C` )pe ЉqAnX o`ala !< H+-@gJm߈cd³~@?σqA ٌ4 0aYhsJ93FK* R7qU}\sXMllPob[" |D.t*."F=bdCWN̴A"Dj k l>J\@Nw0yJ@ 2c`:9Ww vM!`v`'؂BH לCR4 %ѬNF&]Vhp H)dr :,ў72fh`Bcj7ĺˁ=`ʃ=KSِ6N4[`*dUpN4QE%qu50VO>aA`(Ag(uИ+ [KQ&:v5 P VT?;r c#b=T7q Aa?`ʱ A7v'ebx@B͒P,'>cDuCu9{6B>,sWsO:(IP' C"o(]%SD؈X}7IyǜpyCz0p2o=@$ա`\Bag vӗSڔGЉhX,PP%ZQ&w"+`Wl0\#fet1IߥDvUDiXyT(@Z[ΥG 7479OPd)BFX.-mbKL*Ϣ4 ɬzvQ2 `x˗ ZGF6fG# V# y\J rHKe[i{0`ݠB]@xpmu*"M14 /˹\w–x |Q(Ս>q" @@ 8I㨕;cnsp xKsA~ 4y yYyb(G?lVtrK\!8->jԳ̎DUvRM18A(?V!Dt`gŽ14@"tFmȇR)h7Cв;Z H+b@@hK:s8~嚂 $N%5I@Hp>Lr euuP0Ȣ @x%8$"j@+ >oȇDIɄVIE&b^D,>ZPU&ygl8Q0j5 .B̃g0{P#J%B6._#`:b qcV-Bpd%LYJI{ǕaN x7>T$dD@ˆ @Mm6sɃ2 \0RAAS'`&w˩mDͨ|B@1$N%d&3 j,/v\|"a(Q<<66r&$ S; (TU\z%;>4!!8PS#ZM8r"R)CljO8q< JԲBFf-Z0g& >c<+Hɝpij+#=*S-Ԙ4@ڙ*9ps,ˮ.𠺚sCKD!uI  dD<{J j4ShX%NM 21Sp%R5 0(If!P_ߘ4ၡ E{0\,]6'pqb(tϕs3 Jg8rL<勤!>.ox'Z1ʕ=p13s)VɇB9HxR'J n͜ˎfp18K,(/ ]Ò1ZLmc":%x02YH#,Tkٱ1"ߋ.@!x`GL>`$t< v0&!MPf/ =)Yd6} h~<P{/n>@_O3XwÏ_`G.`CeCYr6=s "a*<ԤM}0&bM6k|m4\'0`Ӱ-+<⍺FTqyXafGD qO-Ez<py5c"U3@G^HMu8#G⻮~ 0 W繕F@8qhA$@uh H})}P-Q"2I[6k~Ii$Z IU*{n <OMF vH*pyW=PTgM;L-7~!oMG" =07Bhb0HF8KFi;@&#J]Je 2xK%lyeMf0`28p&@>q$8>`t@qM9 *:X(MLc1L1//(!qy}z0Pj:t +J(!1B$U X?1nF(1| r|S[@.|eȵ%xJ&X‡ >+#0\E} tB'n/a$<26&i#L"0(2,H uG";VD_D|e|(.i &fias;p Eb.1Ɠ]P=`A勍.A2 ' #sB6_Ĵ H(iA!'*Rő22Dd\\eu4H> ` cLB,wƥT/,C RDtF9p>Cx"N6yY Є,N/b /='v~:Mp^3)<\pѓÇ7 X1g \U& QJܲwP^p0_q4.p1=fx`C_qc7} Ulw_ȸGqN(z[c)t9a/",~aAEȱbND-q5sҎ>'ص!Rmd0щ`տ ˫6bTsC1h?7)1su'G` 4 >j?55HF:,S_1_ρ T}G؄C N}K>e U]f, k1aQ*NUh?G3m rW0P)t*gɂ*%1!RKմ;h&Ŝ $õ9 s-1B@*veEVtf@>|LHXP:C?P*‚?*xvoy`3Ўf-,?2CYw⸬q:,, AcĻmEÛS %`.:PGs# R`^c@>{=CS0A1'x 5 ! tHg 3Og q|j/Aa8@6`J!YB@ۑU(43tE:{ @ l؏Xxcb >?(7j^HN!PD-OBn-sB`BUPBGuMc5C29DUGQJ  bpb4ͳ"DŽf@7e>;*b@nAD=#FFl@ ކpHR0@G( ;8XgW:Ro#P*ġ>DbxXHOIo@_1'J.<ʲh'%p!c.Ӡc9@x^A@Xn( j$(={Є?"ɿŠ6HH/|+>Z0%مXYꍳFG  l@onr8PbX]^W9!ӨB93eFW. ` @8 bT1ش&(j60 ZZ_INE VGP*$s>o (vFI1c| {6ɛ@&fdAPH6OcADb{P0/F9*YcԳ9qLdKaph)Mӌ1dH$QPq j ,L(_ncYAn-H̛ @] +^N`Yejx 0DR^| xIYz ;QMsD C\PL=UǬ`YBK,v+ Dbi Ql2aJ2 Wep? DLt =r[Eڢ*@J:̨ie^\FۋA1H`- e  1F Za 3)?Ԁ&DYd1FpI$pq2<# +.!$@.bz5g=Gx.A9Pђajf-3JC0F#a_P A62M:?tC\0׫,ͳ rqb޿p]9,6L+}:EӗA8zs{SNz|z FDc)?E_pKX@@d` 3VL(-h'LeCLvʑpϼO̴p-0l7Q9Q:G* G - &B5K@ -za@1b QL{Y˿.CՂ(~Z/ bDHyqC!݈ yvC=FP5Q`bnC.@+P^4MƃTάl#b 7DՂppte`z9z!ƌg]ӣd%g$ܧCOsDQOD` 'EzF@sHrZ';*V{2'c(@:x[7c+t~Fexc7\Z'q^Ǽ)xtӈTѰ ~㩤4#QDI, ^x&@x4ޡڭdAk™cWG<40PK £@xX*yzs,1PZ"|3c rQ56hXa;8LE* n9{$K])Z3h" :@A"mi^hÎVDX6]Mmw` 1 $>p֚ KFTT!q&7ۚQ*!7DfkL9g6vVF1G؂T'b}C*ܬQ@'y<.DR jAȃm!t%*cPpI!4t_Aϒu \=,d@H. FbT ʄS/Qҡ`(Ϳr;cQ iτ@@BML>Y8ܵ]r弐 !, N\ͬ1G9 _|q}s38?也TN|rr゙^-(D^lCgɬDJ}Ƙ`XF6#9OǛp-H~5dfpyS\+;k5/*>hl3eʎbOܺˇbN_3O$X=P:l"L}&8ܣ%nCR}p%G2[o/7X퇩w=H!L8#[/sM.X(p+#5Һ **,s: Ƃsbe& NA^yoiF @._OF 3R}ͯKq*< cHp>a#7$V/V :FɁ*_6_3@uHAb'ȏ)e.7ja}_=t6|C *~DA t0Nxq:l~!0F] NGC lMr, șDrT1ʂX/=˹ QM9vA, wb* `=޵|X"]P^{{̣Yb (LMuj 2!o4. 3Pi [sCv7S+rM;+8m0qWB̉A3 2',qyiR B\+s,P8jq Yle<0 anX֌ttF̤ Ľ 7CzkrPV]@X1=.E_O/bl;#e&CQGO"lL(py* 5pP7v.1d ιeC ]ͷ/fβ!sOR.&AG ƖZ= -p 0Ih2i(v= 2$7S>A%DԸC02 |A UuAS8 . 1dExF !"G@EK4lbY%Pw` )9~6iF[dꦂ3a)@*d&p [\+E` bXp}p@S8>&$]d_A kb!cH1G/ЃТA?Ty&f=dYhQf/>хP5z{A.I U)i!1喏Ҙu+M(Z7(fUaA%!WMV뱖M@'d\v!Ip h~~jFBE%}r g{@]뤪(! ަ.̭ԥ\]}`~(21`EN05)P4e!WU,&,}0<8`Kn]3?+EۗӈU0 jbS$) ; L"dM80uW?YjaK dDu2cJX5 } 3*0y6Ee\`SG"0e vc2,` HywC*D̀C|&Hh1NʳpA 1#!5prl` )'#; AsWh|8& {rsrd8' /ibv| ;R9vUZy-5сf1P8&$W'3\Q}._FQp8Qu:L28H3B->lT s^D %eDix,1 "C0v.$"+״[SW Ɂ+IEI'~JmUwPQl%m= *^$jB9׫x%1F `E6@9D@"UBEң(q^ 'au0xB*8ڭ,y#bJ'hmNS gzw6'b (τ3/ e0@8nj#byp zxZ0G11e=*޲n4)n9s"V&"2N  i€j,^Kᵯ ZC+:< ^́Q_ k"bعCe< %̼lrv-ol>"'`׌S֯q(7>"pBjy*b2ܽacGsŸUX\,EKXy` Np>D=GdBh; #|A±5L,ٳwu1 1jQlISZ0#n;k V4yh!s7gf^`D;eva}RX6,a2pl(bcQ#OB\9dL*\D_+Qp e-d%wQlb7} FuVOh5$Ft%LA~h - (8n^rN bPFwA}RƠYk&Uق(C&'jѲong `sY ј2mU7D؊a. ^WgT:@#MQD/@qj3UBl DXQ2 ,Tj La# 5`1>UtZ V:2C.|>%!?ecH=TzVgN\pj'Yĩ(ct7λ%S$7.(Ȑ F| vh80w.Xϩp<vuqn x^8dyD vn0j 3' C`0=6H_Xl_ 0m+%L8'aQ&8P2%C7EMC:32I¦T\-0֙C=K}4s P *bH&Hžaؠ2cT٢1N MBXS' lԐLQ؄hh.05 E2.אP嵬jp˕kFD620@vhg<. q8rx`xE;'%d$:E!Vq*`ZvƦ $`&FS0]ЏlL#AmCe#.5& bF0P@l@>cPR ECb66l@>XD/4Cl*E~&!~B3l-[SC^ oD,JɢyfR[i"@Ak,;[?-/!@EleB9XaO`tޘf9u)2Fp"HN.쀵r8u0LQ3.:z8#\} <XC!@YNl ~^1.ywJ%$ &) 2"d"'F @E")WUo,}p`^p X0c;&<=9sE,=2o=)W%@aO0j zI~b̓386x8^CL? U, 2&]~8=,n02zba"12a/.P&ǐ0sMCs&e #9Ɂ̨l,@C#0X;)qot)x)U} RlACT?9NC$xS=ȇBFb!!&BY,P {z";VG3VA'gPt>+lRiI /M#AGP3=g4Ś?y=<`(Ɖ9Ș$;Q|HAMj3)VthQTbB(I`, pٵb Cb ]&Hp"bypEAccʗ1s"`4Y `g\ʁ&2D @?f ~ ( μʌ4DsDYrs+&oЋa@+^V79 il,q"ZEVhT>(DA6C#.dB? 9R$3Ѡm0XU.\,P``=$רӘ4G90 F+0UJ vZ 4TĶRpPm%j?(2GaQ_HG;+Eu8,]̺b8+"jPdq6]v#d;~%+Ȧ3H\cb=;*it!;i_#7o挳@z g0@A#[08⋫,3l'=P6'EA}ƶ<w،mZ{LCW+dNzsohr%E~X PKU2`Nf/}D1  4f[mKS2L!# c Tӆr}I:'6X ^4!3U>&mտ#b Qs.]f὚@;YNG32CXK%u#Oa䂀i9<TC a#f?(l<3wQ"_)8%L9(jܩ.@1hbvvc|gv;=W rǴ(%y\XRl/e|a)l6Q`Ӈtp1kQXDrAViXCB Ût2bNŜ+iY`e=VOR? NU!XM0%  >]Tij+p2`L0o}G&X+f}f Tt͉&C[FlY87qs7F\oa2F/?ތ1ABT>,0JY!-d3pÂ@#=2s CvhpLn*!kct`sfM{O8a7.ȑS6Oi@ɼPlT,idz3vw∤OV:khIK\z!x?Wv0Lf̤ / %|:ԸΚ)0,NQ0%8z(Y |o%el/@hj>'ʃܣd6V{h+vvHV<T `6 9*e] mt a؏+L0@ P_l ,aуQJ4.5)4KD a3:4ʜ(Ţ6#'Y!>aa)Hln E7/r ƒdʆXQ9x )xeU"8>x45k l@: fA<yq$-)4fpsKB+2 31C6*7>\p=`K,љDDO-\N8fh7v`F@.R3r~}<넍%!`DPpvA/q.-Pq9`DGE^|4y& ;B9j #?FgfDfzko63PTa^!G=6DAUK KzvWi c.hLXҮL?A<crilr4Q(<@"$=L` @-|ڇT] D8b3(AȁN:qeD)Xs[E4^wx>QV!sdE (fkr< RRh.\pԵ䢀>@AcZEs6@ t}8.4C%R 3MV `c61ݚb 0]'ϸ7X3R pfؒeN #91E %@qOƪ0 1`P/R(پAb>شY= $ ؉ !E`6DlXZJb B!s"MS,D5@R̀=Y~#`{rD_xR`F+0?Pr9 My?̐ak3 n{6—yBq e[ecߠP"43d!Mcڙ$(S1ǯU @׾J8f AH2 $p䇣X3\Xf#, U@aUys'q2X\Ll7烪 zTɕLb/#aJ)mm ᛒ-cÄ'J`UA'Eʺ֗@/LѢ?qg#?@Z+0",e A>(L7QkPȬ0lnD~  EEl`*dDpᇀ"ЎVi,&4H0DG(HW3Y aڌظ[CHLdl ,3/ }l]% $W@q"5>F3Qx9[%.F:bY#Bl`1A#V@- T{Lk#9:PEPL#w1e wp&+cT`pq7k'*z1P +wӋG}~85u_@)5`%+H(}L)tkQYEKQX3'paA:-,Ҹ`qk  a~^VD%|+ q_${kVg!RO&0Y V%lw=>84ܟN@DS2HmS[38ve:"yc&: J @ =L##$u9 RoY@LBOgiMAX{Px&(PM wP0AcH@5ZC'@\6 ̦D@ h u~YAKbׇq*&H<\fe>qE s4^"aƪ(XY$i8zF!:U \P"r'1(3% 7LVn32@İq5cb@ 0koAm* `CqCa9e@#"}b/넀3r0;#ppEM1p|A MS<* ;_r` J#9,Y$ȃ x'~4YKbpmH3Ux1{~DLTNb-V(;ɋYq+ɡC\=yq$qSj'sh )2A<<Y~N V4@OGR}A,2SJM\P11o)3&]Gm  ȑ s B͉<p bN`uݘ618a"ϾJ-@ Kʉں`b#<:'\^"Z0&k!<&POώg;qpXWbPYQ8&hg9 u3؋*@*ٰ+8CА0YR v)x b[6G.pc@ ༱/kYt u$#3CV'+8 Ze-uA C EFcosgڠ5/dD xS7k}tʼ@V ?SX,)\ɹkQ#N機Ugܶbs3:)oP]!F ;%p5Sf_i&&``-0p`xq=&N0;&!*6|!@Ú'ٹMw9˹\F&kprbRQ1a뺸G249*b9TG?gхZnoEͭ"Ah>U$!)`Mfplk$W-QyC56acEP),.26( :V:.b7_AрF@0Lo)2LGr<%l \/ / Zr;@N~9T(ʦ;R߱0`XWmQ],(d_RdLC8S7,P7!qD]/Qĥ,C6XQGmpY`WU7Af( B|C1CG2Ɩ@_Ȓtuw4K^Qr9 ɇCu<0fH t\e$1` Y@08!`ާ{D+P;@3m߈n >x4PI~gn4'3 !؈hv13v"W/ٰ6zM|GFd)f0"<er+XHBxLߜJB6Ks7QԭqboRAv _hYmqUvs7$.:R0诃 %DdxG48DlaLP.;.@P?9V5#K&0e w76HVl0/0wh>dcJs̪2:tDXex+!hK,h`nᔶ`5a-@F>ývC=  (Ť_F/\C"Ҙ|v#5KZ$I9(a ܣɆ( Œ8ƈD$IlNL;9.&Vw*0cl' 95IM9f^^={W+љ3`AvK|NsݜnT(I'2a?@*WXmP:ƥ,0R0݋|9,fFslX|!p/^{0wOy.n4h2֥h ZL1#0:azKqKcXJ m7b^ B! lQψaṰxkV6qr>cd,}rbk3zXԾ"f Aa?2mDʻ?.榣y#3PHnj'eZ18@ uopCvI=@X" ,1SajBpQ;; 1מp̻^ s' #6GE|Xyɉ_9 piQ[@_Vpo"p$TAd_, D 3\|?~B{Z7s ޡ+H9sG@8ŕQ6 @h\N/pxuQu{Wj0A 8e2 g?{BX1n` #Syơ`cRŃo*;P?=5ޟ`3^Π<0ruDk[d ++]Aބ&=TH8s'in+7`A-Ar b7 .V&<@J z@9-3 ~ CfSNe96ۙc@[bYH9e ňZlfjg|~.%3 No" Tr D !O+M$@ {LI£BpHH]Y`CJs ԹE)6Ca3&*^ĭg|tKX.=gKE4iCtC9NQ) R/0. @mW!yL|æ+H =q@ۋbWfsdGň@aаHU)X< mA/NΆ.'+TΩ7s r-dfcS@<۩.!5)y`nAYZ/[l.!r'ɣ0t!<, Yd>< ^w/0eb HcRh@.0gܼ-\r EA;?CN~f'-Y0B5(Ns@& I3 %*6C{ 8]"h Exdy &d-D H% DN u>$4;ρRG7TCD U 1ŘvۊV_h&,.(2!kJ- Q8J!y=ZرU^)  ӸO 2B rFt gKԷxg00g'>9YыRK^B`pn,Z>{s3({^A:\Ko(QmP`\P(ؖ9(kR0,0VWpVERAqlQUwܪfq̵@lsAfj+h˾*@t@q'Y>q;8=]K3^L"Xzd‹!ca\/d( >F@"3znpPY;!.&j ǂ3C=vDH|DlHy2"U`tYm w,V>X`>.\ OLD@7 B35`Hk'<Ubb{U`ѕ$$HE$x\`*/V- He"57+IsgeEBҀ0-~@ '#8  !+Zf#H@u"58q 0۲Dlr JOQ>*DVC1lx?"#2!,kv$ yBq*^3.2%*"uqfh'IJlLj!(HDVf0ݲVt¤O7t ?a!M-Nʞb,8|Ivvt@[Me#*@v`q@yʙQ8C_fO?) " H[%e8Xr|\?U|GJ6!Ga@Z %z( Y`ȣQ "u# ˓]@E?Y%*95\A-{BgH`FTjB#ZD 4b)Hj2$ϓ y)Bpy(y0q< /$]\"C DIW}1т. `Ϧa{la" lD(_B.f@ s8ӥA 8mtu 22sGks-Q&QrmS +'aYL lwBk4%AKًL5T?Ds|!0x5!SAӹpP7Ey& H{&u eJJopipo8[v83h6`o(؃vK^[@,bh ;p.r`Wn )$Ém/r֗>5UZ0QP *g!aQFvb<@iTX3 rpmH4o\O>'&\j q0<˭])/ 7rʝa q=CV=%n- ޠJ@gO"Ls80O39dv'B9+`_;698=Dł2S0-B H3_%@7Fx`[qq-EZ B'zzq/ZzT .t#iZ,{qLP؛}`a"pAAvz `\( Yѧ3c,\~Q\̻s' tڲ"?}3+`)F2f$\ $Ef7#fu6 !&pPmY&3\VU``cAChc&T)v [301q c!fcA)X - P "O=Gm"4@mϩv~f4:qAcL4SSy[)Ƹ@;KhxY$dETbU &z )b(DNzYa8L /00>e51#4"_ѐMF+#HVa.E_ܬ"K ae)WQ궸C#?+X}f(񛆲q$Kfa1PΌKs5TXZH`Sb@B]j?r .xxK_#pγ449J`]؆9=⃤_sO|0(p/[*UbX$deI-xI%AL6awp3,"!@\LJ(C"7┽MrhL\2XZG4#.̄&u!0顢i1!Y:W> 9.:DE[^)piCu}ь5^ f!Qn;l̘ EBQ3B*l5JiE9\yyX#,( ?PNUx)e b %Cfe歈 ̯ah,)%tN9LC<\Ⱥt,} .`TUMrXvQ@7yVOr،mLwm|_ߋ^޼)] Pb!;Drpw4.`h^hsxP?46)s%8.f8(An =3x"V(w<[w5~82 Jb[rVF$q[ :f}(#<\`78HE.F,-;0r |bU" <v?ԫ(lSb?T|W ՘Pv [-q0|Lpť3e,H[ݏ(,rNfG'K (ѳG8}H3*a "oٚ-Pu1!F96`km+0UG ƎѩTԞ ߭&P\'V /+p:ge-F Aevf;FETU 1ZKĞh/#g"Mdd ~'֠p縴#( *9Ѓ(/ S(Ix43D(8MÞu-ܲ8w/cn.&<=Tij+ks;2,D<Ӟ$ehAfZbsW'BG (Cq5gVlX:@C8&I`-LH"@H̞2t먩B3xTPr#$h{EP odC&p@s,l(< nY9 4B6?PG{!BVx$ d=:pzasDeYd";pԾr6@f.Rk=K1<ahVoPm=d\.S+²g;Ƃg:.ςމܣ,Ce/O IEmnJbҗ>4wȀn,c@@8?ga_ \srs^ u5hsiDg\،01ycS*& +;ST |KҞPZS$`:s[:DE r*0w"EH!(̛S(M!80T3xC]E{86`/IuDʃ..'| B،0eeHP+X! q%OI:'1/ ɗ R.f -2xHw[ eD 6vU8aapɈl ;V\X夡聯``PQpdt@+(PL E{$R ̺G'K4bмGaO;TQƖY?%_ K88~jhZ>b< #'_b"$/b:`y:@B!*r.efnJv3qlӂ+ Ȗf\R*l Q|V~Gʧi逻 q/c9)s-ʰ`6\4vs溁CǞ'mm (hǓ[1ˋ rLP rX3FfS+32?ȧ@aV f3^#a >:hCG׈.Z2t&i+l AFھbhc5B !(DdFb|y8R̝0A920jA||i1B mGu*ّLk@!9\5-'H85`|w+00!  QlP' l0,) E(PEQz؎n n+6! !@3 +&  *NxV\s\'(Q˳QQ ;F O& @4rÄ" j ²3k]8vIua*UՑS& Ag ].jEɃ+s;!3b6Xn,:˘pQ:e>r#3$Σ9? ac^wUSԫSq@d7xbs_Wm,SeaYp|=M- 8$wY,OوهHQcO+& y0H`CC̿)c7c^ TLKh|¦S`aBWN_`M{lO.9fX6eXFDLFlbܴ^&ùEou2 &iCngj>f`@ u?p` I b؀MLU%u:Jؘ`O^y#0uG5f66Pd; "?,̠e/CXkxefqKlg8Rxx0p$Ql8ܭ[AeO̫AuOHm<*%'3z/[1&45S_}` bq`օv~H3 6~! @t `cx|!@Xhy}9(ڞ43DlnWB0{?oXD:xpI-T1f (d7*ui,Q_p#D;>?cP" Kv@#)R!8 nDB3 (E 뙺-VAbh.b=dQ?UmhSP5#>hX~0wDLV]2Qĝt40 HJؘb؂^rr$[ªqP 3K -:cR؜-n1NsM@6~э3_o+ɬB@E/l:(gNP<4* l$sUfUF9 p(>@w!PHerPt11͈ QaP&f@GĎ)z@#Be;6Hn$XEE'~ccÃ˿UGh2(df>j^eDܦʀ 9=HEG`){}aب%ḍ Gs6XD"#=)^ǃV$hp{ |& 96 o9cќ76C0F({) 9"9Īp5łlLzP6/}"-p< 9F[=5ƫ)8QM B;Lq`,@Ȑ 5qVB\3*QS<ڦa`7~~gL\nKǻ"x0~!񊀁?/d ~5U/a ]0 dqԌ3T-Cϸ!6WfV͌ ո4; P. 7),զhX SOb4Ҩ81E5f] JfuYitndY#IO3 qSF^|˼ `v{& ɶu׸UPႰ玣4 p6!vw#b2aȊ$нڌCb9G4[eA?d1:q%b\&i;RF=MRbWwgjoy@gyhSZ/~ 00 }=s1[[,e39P EB,уҳ11nL`&Nֹ^cH5/ufaV6F͑7SEN+`cY6K.;Hg@@G& bn8hZ+"S_aG& AElC&o-ʟ`PQA^=myBWSCϧҕhxK`a x_1CLp;6L@k<#&R fp`@K¼m>!Hl"\p0Q~ɢeh2XՆόH3bż'4;fM&3pԋ@gqΎ ,2JUxy~~z.xm+´m=r)p6{_0\zh706#! SG ȦG&rt9೤&\! DʉZAn#;N'3u q4zP\<8iZO8& ,;Sn'K,P3hxL4K'*w3,P:>?1,`G(T71gLS_pnKPb.BWԌ=7pJ$v82@nwٰpl&8AMP@0f4CV T!{ CC+ x"R lN(N}Q*dڊ'+:َFT\߂! eK;#&AՖFNm qU6b3grT>"< i] W8ݬ`fh; +s tčXna(,<2DŃ(`!sǷ ʹօJ"jd` qXniݕ=b}=-LVxј( ;pi.*6D@ Ѵ akPD,@IiT OԚ _jTaP3[ruv7MJJCަ<=hf1֥'ƀ;rYȯxZ .%.Ïx2l Cz`6g14e^!=ȜP Le[y3#xK$ů"fA͂Ÿr3A&$vbBC% nU*sL{BoF@YwX|&ag'pF'V FEpEG^ sKe,d@, iẁ~2J -PLjStDp|~G-{t;c˙*/hmfQҚ9f i"{184ɗ xD"Cpdr*hKf`S>~uE1@n?1yBpzېCpZVZ>eNRhS?~t!$+^;` SkQCQގ u-qK 0b%ȁMs#Y\kcaFWk3 yEɕb~DzӡdF`4 S2cP `DZ2amB jÀNNNϙ@>ez͹~ PI^jLM8tjE`a Lx8$"%·*KBdħW )`02F%gz⁓6'q?:1Ůah :> L|KGy`OD1;l+S$j/H}#]qơftdˀ rg-&?eck*m@Njcәn7>)Ub>A洢'';a?|N߈e謿"R?/:lt+N2h&}O)T"3)[E1,|({4{B9> /DY`{ryf!…b3z]F5hl-Wj#^){x02Х`?@ s 0$4,nZ@a< FcNۄՎ ?a&Ŋjrl7F x6k@Q>X~ *"  U PC!y3:I *`<~aijO ڄ㒢ϱr)Y3\8Rb9 $uZΏ/3#[$PN09Y`Zџ멘$1a~9Pjn]ۄ`_PA` DN35ak_D N5kܠ0* \Xʅ4bzBeC5 %-ۆY-¼fBStByJE#x&~` E5يu 8 A@71 GB?x/"-9-q4C"RF(#tw3xdy1-Crs*e#!må2 Q3U\Baefp&cn8ZQ.;C@S˃^„1rH>2,m019~[1>pR SȦH[:1Dy  4>xڄp4T$_ۏH [W_0X#Cm1b0bea@gN@8CJ 3A;(la1ՂQS E(ש),#'a DBFOaTÝ@ >tӧ7Qp',AM]0ISqKzFܵ˳x>VD G'˔ڂV;f Ar1c=7M&N9D4KVU@` "X|w:=-.fC ;"IE&8qClcێ~Y50%Ƹ9`3~D$] ]Š}rB1 s3+1o 6\rA<ܱȾ|ܬ€+*Ў澮 A'5`nen9I,ƅ3HĢQ|!2.?|\!F®bbS3 dܜql'Fpw˺:N$n Fbpg:iN'G,<@#oe.&/d" 2Z!rvRXCkrprF&s <0 v. , Zu7<`t\۶F %A1ޘoKt*.im kC)/ck3YxL .bTZCc5`;\\:+vvJhg)5# /(YqmPnVpnaL{⢂ wP2x% vzavuNSnL,|(7&5uLi9 )3V̧f&e1r!Ba xB=1p>Ic >gɅ5Z8ҁBEׁ?~L̞.Pj#)CٌlZ)>D YaÄwwW73d"ѵ?֙l]H MvAS `2ȇ(l¼Xotb82Q=JdjX $6^E-1! "@yNC=-l9s(V` bWd< H`D  f;@^}RTr(_̈( lo\us d9 qѢbM~f _a1Ne {3`ڸ' @T0 |.RжIbq"N鏳;~aaUȜARkͲx V|fZc@ LZO-Vf2}d'f)(ݘ'"S-U}fQ#.sќ{+tM -AMHU MdjIdX@pid8hŨ~l. zau?0P`y޽Lt&ޠp6YB21'00jȂrBa[s r&b { U#f2apԦ`<%:?H (i`iRv K[A"6aȇ6]@kA90tNJV}&i02ncplXP2ݘ&#5|i-(C=K o}Ci.A%WX! |n' r*uG3;%$ Acl!.Dw1GA<]̍h/yS=-T 7YL|7#f< Y.<:S!mv0AcF7(lsP>E@w߉DO$c""GB=ܰ |A( *2`d <;V42#@ ԚQGyNvKGV˭f1a -!}fC]KU %'`iU@:jq^de0DT$^:Z @QYIJ2Ƣ`6 m ( W04BᶋAZHEoBpE> Y"$A-1?6p#̐Խ0$ʩNG3*Ҍ`: Q{Iֶ74!6׹wUfQ6B)m|'}s6Sw-O 1(q6 oG#|!L[Y>:aX՗1H1Z$hV~Jn tV;b&չP'CM(\6 =61$xT(E>AHB/0{'%P9( 2;,WGHMyu ra u-2,;b/hp&R|ec69!KȋP+nxq]˥6~M84"]$ttԱί(ܛV@*10>60|JB C+VKJ2*(. 3XÄGUTgrJ/C ;4!R 2. Q`8 wtO]u/E~|A8a1Ȝ   0&ԸL  Ќ`Y bc<&sOUBw-AaL 77.w4'Q7d/Bffe-yuKc t\f\СG4:w d-k "vf( (Hܭ6 Ըĺ8Z}F{00%֚vj\-"J9zC_3 NfLLٜQFI:8fŢָV @}J87 Z-ys8hP(-raAM~&9ש AWzUK,P0NJm[;,jZWyx.W^w(zCZ ?pߗSg1y0уlPt- XCFbb<60v P|FLV) ˁΧF(=ѐsω\NC7Le @טG%x5b ୴e_!69FRr[bC?jrc.ahS;1$YJ@Vpy6!Gy1I `FLFaE (s !KYa#"@[Sz"%BF2L3#%3̹PB ހM~T;֡+`,B /f?N=)&vsQ(~œgť`VF&=2-2 L#WAå>Y_N69ք+5XTY;j_q6HgDFހé!23PJF[Uo4?D-^\Btlr<8JELOyqL lҰ\G`3])/Syme?14w3Ft"Ф^`xpDa &[S24q)DI]Tr=~UҐ`,ʸyloCN jy+TH.!R .:4/;z !5Pڗ\p|LE,=C&,(0:8S1FpCg .a^ajt SgĮa\dbs{afܨvPj p"hP€"X FŖU N*:1B*l,16wXZ Pvoؐyx3rle@]Bm'K-cLǜkOsP@t hkksrC&!b`';0|£\幬T̆>/L׸JBȝ-CkByjnx)`0 AVIl(=5Jf7q p`-7PϡAelCz _q. KvP(.fZ3e4T]n w҄n|w„vR-GGv ̦%|aJ @@옂!d+ h%>X-ABitP"C3g Av27ȩN! Fѹ6S:DA A q96SJ50H8 5%fS%w|@G-#/q<:2c4,qdbĮð LyQ`"2%r3 s~~&Rs*Z\,!"i›=DLM(5 d;+ #d"W(q-SQby~u @q3Eșh,tÔx{h0i`%rsUέ UܬXh  xsm l?+dp~u qsTrccKV RSh#D ,GUYwBh+LWeE-%ۉ#f%(@z.G!|ٻ@6 Xnmlu/2(j=Ƅ9yӞL ;E344 OaD6؁Z =\6  LORca v̓2xD^Lj̺8XVT7pmb۬0;ʮPreT %5 XLlsJ"D"O`4 ~g %Ƣ *-`AA%bzg*[^ 9Da87ɝZ ,Ĵܳ0:0_KA{CqLse!. A9aCAZU͒T\P8dAg,~-MF(lB߈\m8@2n >&O QHWQ*Hayl>u5Db8xkpb6q[ ɘv(FqeBŦ+m1\& /&Dqn4#m*j2]$p%O،=e@5cxeROTRn BM>?`cf()BF %xӍ2%0cm(AҬY̅{$3(Z R Cn {ΐK]+:o جdf#D88MGqg0cGs-G YÃy $U]hK3 e+ 12F~F CB/o G@̼Y e_A`Ń :WՂ a'H .0ˠbo64r2h\,0S/eoJ F׹yg]8,w 2%jTLnSE1  #8L>ʃOaZ89* ևT9 7e͒= qY _^"g]$! C0#\TP8-*bigP#BliOPԺ {I8Ɯ ͎ mC%i\ʊFm>ЉY9T?cqBaՄY1.)omy'8L Alb&8 `B r -%ѸAp)zjpn/>K1F3{36bĚ=C"oΠ 4e AϹ+dM5> m8;>fA!1GP4^?7 Rjc5Sz."A WX{]١s؄?gS: rꧮfQ8VcR 'JǛ89,01``=!F͔Y#J؎`AG2G$sŀlvT(Oi!a$;. >#) _{y!y9X_s :+>eN*!2l7B,i=~[~>!``";2rZP#/#VY gDM m35 :sb+#747B`^@ö6%];.p|\!ԹVGQ7 CR֬B%@$`z? #p 4nWTXÔd#  &?ppxKCg #ȍ{q==,)X2ژ =Bʆ"9眈 FGX+`s7y:ϹV?#WBbkH˖d(s4+@%A1.JAf$PH!Z!I n2 FM7b!% XB]r4PG3`2:4{0gACgū (,\LQ89+4dhiJV2!`F/= V-;ƹ1 ܺRr)S.iVV}ASs,ި 5N*::b(|wLxP9CiD n/aQٸR]&\sH".. ?3=nvg8D&'0L2̙11`r;&3H^h4*T++Ɗ=`P1>ꚏLÚ Vț$Q}hˀ &vBVX p|ɰMA "*yrQQ}9XcfRGh͐xBqDJ|V bB+̫٠g ̥ M&S 0A04nIl}@RØy;`c&? (1~x+9c[Nڂ)۝zʠ[휡2AK0S@[dȉI5[909j]EQȇ{a6&8M.‡(Y uHd,W~&u ȉD9t_"|-=穤u,Z/T^$?bXeXfl2)/'5Wn7CCc;i׼=FJ2M`ض'` t-0$!Gc YS['pls8&EV (8, ,7+Y`~ D^$y$\gTIDLoAeE- oppyלaq~Ga4 hC>$[MдVGSd-9 2 if%e3wf/{ l"q*~MZ?dC4* 8 *9][$]JV66+h73L6X ,(2ݒO2i e1UO&hZgȗeC]F|sj#)p6qdN Q3\SnlXuCѕ$7\qP#6Ÿ:"Zæ..H d%J,+ i ,@+3™dDBPZ`p8Ĵ9R+z1`&ӽFUe0Bd=lܲ,pde$zLTiÖ9pdr|O)F pL8M&\]!F((} [Mw lC" C3GNZ1>7c)u T'eu #4}CRNy(n(\ D//nC\Z&-_FZKQ(?GׁDRHO̓bJ_D‚nE$UiEf6'NctL`5JS~q TP@ f= ŽE-Wv0WLJ3 Bes.n|(0O.dRbhG%2-x ,p H]Z3,_n,G wTs>O%99SB0ȱ0 J}eUxB.|Cg['S\|ˤg"@A3(QqUUPΈAv=K~OQލSHa^)l=|g.C`䪂3P;s5S,}KG/k05gԨpsj +5Cӈ ?BCS~hHӌJnu1&" Z/n`pOfj7xԙ^)'8z,IɑMQr!_ OcAGyp'qTI'0ؚdpN tN1€Qbd"V1l';Y/V-!-,`GFy͛ˣ@rWsusmW e@C+љɉs;ZL 5awdq?;9PlDԦ0Qd&e<Ĵ. t\߻EscjI 1$[b-;(MmPAr^'*F͌o[w?rg !*LkamРpq+(P%~ȝ#e*[$SOrH,7G{܁~=N1L 7Gƕ~cUO3?,oC 5hvղǓ8r<8Z{a5K/GG|&D 7Ȅa< M<3Nc8JNSFb(Zc7/(p_pf!0ͪks3PQ3(K8L8s(y,JHg;!N8?nܽo"=k?%qT<.*K 3rM@#&]ʀGO5,v8P)aDXr/}ݚI,6?0?%(riS9'`,~@,؝1phO=FVb؛pQdjQ;@ * ZiBaf &~0`˿zL\d: ?&i\|5 y>fePf9 TI{G40I4[7> ܎±8WpNqTf&p1 nc/mGl<\@Qa2YL 0!ExDRĦ$!Z:1vѠU h̶WYCv d/Y8/GP8:f)C }݇<$[(/ΡyDqhfs"<GqJ22 3BȐOA+du.,8&nƂ0ZPJy C5>'Qr\Ą ؄. Af0M611 2EĚG %J</וꑉ\Ro='B”p>}B5fL,|9^'@peL jOB M(]L~cYA={xNYsP$ݶܦ7 &ˎ^5^%%BX7 >+ t&Yȏ~? Tt!sUv01c&j>8WMre+,1)=8S{ "2 vݲ,$;@D0C/% `nC𘫐̩#cy@qkOۆ+ `mS)j6)A $1@*ٳ̈́}66=yt$@->_18K D)K 7"8h<0|[;E\F) D|#ПhNJB ]Kd'h'3̨";P`FCDYP0`h2+~fe[A-BB.Y feF@j?'T*DŽT!ӕ*N;U%%b"C)FK̇l' H 6<@иSQJd`أB8t\EF V0-dq |@˼I]EDLxR *,yw8c 3ր zðKi9 )OHfeA GJQf2˩Ay>P|B;yI6>,K ¶wp=!oAg|"Dx}Gx9pϏGF|uY3x/-1mX[;*!\X1tA5lmXDuc1*`9)2-؄}C_E-$K *̶S"l&0"̂2yQp VԳh;5 6B-j~欆O G;Gkov}D2Ұ =gA0̠Szmn4guK&5,l/ ˣ"(9clZ''$k>sqsɯfiOHnBJA0`ToOyL%pNj9S9«sq F7{?. C!L`8R#kJ,",,;0^LM &-&:ب |_Q# (,AcOISp\-g̨^ErL"CgRL`ԝ UvlC/?qCC0)`(#0D7 Qٵ]"$ FeGa: m*bT0-}" \y,6VcȒ (6@:R،",pJnP>W߅b y 5e*4,f!j\AEN-bE,bU:;[蚰dttkTd+uC6j-D\hJ 4n?OGB;_S\s ʡGT=?%-E'U wcdY< =/;:9FL93 R=Pxv j,m w<[\NM>%uv4B1cHEZ22!Z'\obd3@"SdOYNE/̳* `ȱLs_| pբdae5 ,6^%LKd=L39PT+ 0p㣡3"0@xiXd`eUҎ2911Q` aۨ!(TIsb^~2@">LK7E;d !=@#)kD%y K <s+.>6foJ6T:Pch3nVYXE!g|C 8@--wp9f:+l/!{qC#UTylRi˚-KEj`$)} =g^B,9&U4 [H<3S:\H j?g$+06Ԩ;BvSQi),q% +О }G+GAYB @:0Ǥyi)dёspfAݾϩg (_`δGxCIƒ>h> pYnڊDlñ3ǁ#<}LFDdlQ,i#~7o"*`³pcMpY*n/pU@,*Shw$ 1 vh wH&8Qc Hz 3hgѱ;Dѹ `8JTq3'߉{p!$Ҙ=ހh" :%,Y)b;">@ $&A”  C\Fb |Zd J ~&q `A Hȃ>X V-=2 l|D0Iv!V a3n;'BbK")%jl[C5 ' ._*?DڃX=[%a˘Lj3+j' 5)_ӈ-b`>H@nXdNbhI9~p H-TlcTa("~+A.CU}4.* Q,\pART eNI{ |&X0KN {> ¸V/P,u>KvKۇ籁m r"8K8 hRO710lSYCJ-jJ6TQG15aH!g%1bu*hNc_vKg:<"*\B;` $Tp FwJFk6$A,0 wu 6@40Yo s3[bp.42B` (&:38# ]u a;FO6Ƣ .g)q/Up83ؙI!b'Ez0}D,#aȘ:E$Hɓ#b|_Nj0dY#ˈSad?JЀ 5 5ghk]Ry|R#E|q j0,!dds 5; @)WEBXܿ :SexH`f^!P>[wraJyJ(#s<3`ĕBGJN2hboCz\LK3!߈f_)m6-e$gjQ:D|[qmYvRS#AKW'PfZ(@g >vC KVF!0@/[4b;sNtAV\$6 X,"vH4N``t幋`Rn'_"0 \-26].6MLœ* &  Yi buN7j$0U6 +yaK7z̪Bk8\#f JF6N@,Nv䝃@` }qBYTBB|qHzB&te{Fh5l~ (r&.gy#NC*W0jKB"@9sʨq $ Sm>Dhg14?@y"pB  fEEMt jA-G 1W1+m@ 7b-OZFx`D |R ؚ&,{!6VDlh&yet,N|l08ARI , H2") s v v*60W4gs*lNQAG8>&W+ k8-I׈k<GUP:b;Mpt:+wq*` B貢 Wf`S ܠTh ϧɛrlRfN=X*khpxs NzM0@W l}Ŵ6誰*#a2 qtb1ph􀘀u`FE s sD,(|`x`̐l5ERB7fآ$mLf,`PQxXډ|#⅋Сkîp‹@-H{AW#%01m.'D1$aM \ElXr9\@풉7X"lfH &oL\0+\KΣ5QAsԿou͙G*^Dn*[b11SR8r:*`0D=k[)!l@{ Ξn;l|jbj_b,K! C.2+n`40J~e<ƌ8=V*嗛!7wc)҄Zwt)a`a{Pێ܎Dr1)#IQp""T KDN EJH0#ٍL̟$4p Vjv]\!ƨ=L`F\H fІ'чHʎc~ qCgs;8pma22,a7ype&O!O725N#4u8g@QSf `15SBqDZǍĬV@<"Eb~iD%-? Xe] Bꯀ~q1S)?Bܦ X#bb,Vٔp惔|ɜH =`?e/S2,Mp#/X3PR9~&ebcv-b8E-A׊#7% D/1M(LRt*q $ge R懤aM 6YiNc dQǙn`%B%F*[vcud)܏ʘJqʑ|֘ 51.-. T Tu{p~F 쉕Zgda{@3lx|Js*LB|+_K3{4QK,fS e&(2# s0o }a#J)Ƣr)CGk q4 X7y`W \#Q]0^44A1΢]ЂڇGu oD#( L^FXv,ȁIOcgc%45YIRm %։2,=-&SH0>/d?h;i3rF `i jAv#f1@[I3(6w-2šܢS ЇL&9ˀc_h@*`Xp$1E:e=X62?qlw̛$N =OK$f"D)K=ڋ= KDP64x9 KpKG gI5\;O&CΣu8 8:&"p Wq2P{A|C1ۄ(L sRfa6{uEބMȌP8P>0`#^$BRE Di!MP>%x`@pYA l:O3>fݮ% kl Z& TȰ> ̯#)d >>ZpP@ p/Ke >wn)9l$$QuN/I`Y F9V@/ոXF&|y,DVC@`u!;2T(&3~}ۊ#"twY2yu9 ]\!aZQ[JOt Mh4ßBcQc\ЍQ]6'hpQ/2&*4^c9$g'"([ e&D@"! bPjg<-;Fcn,+zؗ8lƦVF spA^ 7aNR"@eKcham dcexBj/C l[m6>Ĥ 5D2:S蕅0+?è7_(+Pu{3V'xsb2\]5`.wᙄ ?pO>N {NbiY{ðxϋQPCQةxEʄ |&XӱN.fP] +kF :hCEvQB-+@n&$60׬VԀ#8 fnV>#63-8pBb ԿB)%L)Efd6*pi(>_ 5P85:Nn(wBނN0(ѱ !}HtOLH%f84 -.a 7 `ls,dZ:>+@23$h,Ԭ/e '2~ tBұp)%/xCp#vzӃ64A,eV%2`{퉑g `hC,4gb:H[z# d}<ƍS sDC71HcsڧlB <+N Ii>| SVyA.=c3 "ƦIU{l @ W=3XÌ(IoG umYZ14dfdx9>;1*Mg'p1SQ/ts3h}ϐ7 0ed|r PT#aT 5b(T{R@.\}sVe2` Yf뷸_M#%^g Qn'DaD9>@}C L>c  ň)a;fSf‹@T $٣&gȏ1q#9v Sz&WC"0"7f# urH #&FZB&dZ&UpX}>&|W`["&΢3\exXpv65@T2IXfa`AyQ9WLX @yz(yx,(rC;W05:W h k0Y`!^flϡ'flr@*~Y&*G);XQ vEA89Yfw XS_5,4"h`.P37pAX{Q0 tj\s< ;Od|M6쀇3"@^2r\ !ù="Z'6a O 6\p=\_ H ~Hx^a)*`7E>2:h%A V^ n;bT-QqHC&<:@J8,h;^V?7+@l(VnZ=+" &g}C`- Jw6f=L A `4faPrr8p5;)`\1%xM` BgPW1s#i"P^[t^ 0-mXC.KRXBoK^Y/PkmbY!bB tWX!E \[++#ea O1#*3Fs/ G9Q< djyDj|Q*/VD~#l161K_14!efpp "T-*i K<1<+(GBnEl\[$"f ~O}%I鮃wLkILh$ "Lͥ6n|dV+$lclh@*LǭNp,n*|yf#`*+Ƃ`wUєa`hWP5 )?6y^'J6[&% !btqY(%$ b2w>|O}Xi kyngwQ N(2=;D Dܼ؏fFzys\%Ǹ}k6 VfO@g_Ѧq0.IX LAZ/o|L?.4r ??vaj%!q*yx ?߂$n!C)+QmLM&n# Lr)Z!{Lx'`a2뉙T_/ XK5 rxPq2 GRJ1j<0kZvrBpqq3!@F›M eܙGn`:O7ݧRHGL+," M T'3,Lg`\9k KnWAqsp,2ؙ+~E&!nMA_b@0Et% gpXhbuf NeE9e[{m`F&sݑenh`CѰe[@ ,dn&h6R"rXMqqm pmBg @HPf#4rt?{8`(g>Hߓ~TYM0P?>DU%#}&e7lRT *k#P_&t<Cxn`6oM]C7aH4AǤ}0hYj-Yr JV+#dun5sc1u\ܤYBqUi>C#^w?}Jm?0K5ָn q| `Pˍ(Zs/1ϟH̰98s.{YU^Gξ9*nSs59JҬ? 0qZK,:`3Vk=Wi 2PL( $<~ K P@hHBbGEfxe`58eB"x6(qAaX~=,v M,! И?}g@1br!,j"x*`&,U l<0 ǏtI`9T1 J( `0W(D؄"L0.:#7 2ItI wVQ ڝx@N:Cgû%s> 3!⛺xD 0LLqfbj L'^VG P@MX! j/5!Dbx!5,f! ,xQ/D{, s͟ xHbObh~DJlq c?蕒l .A@ a2. I.S£bME(Ɏf,QpRJh@+U<~`8v#XD 9 n 7(ńpMfTJ8Gxx"x3•$٠y 4ǖEj bzsZb90\&/7LB%x`CYKpňw }p 1C)25(\,kAXk{ڻ! cĀYR @|3/C2"Y^)0@V.Mc`5ܫcҳ2u`a~.]0  1Cx@ =?X͎xqŞ LH) E3M/ XF8(;b+ x0ņ/ 3S-)& X̩]+pIh0&,Ja\ "|( 3*_h ,*tQŗK8<%MH[=\ųHM6"E;R }<Cׂ,8XgY"qfa ``RN.)0@^k2*DsE1Fo!5r,q RaԸ1bҚMYzfC\ȰnXNȦ1 <"A BI?4tCa H%W,$ }1R,݄ǚBś71&TDx\] ` ,1H0C*Uo1J.w jSBOt  NxϠ b_)00=b<1wkB7,3栈B!tgs1#ܴj!YjI %SL~,+3003T⽂$hl." pUhA&{s#4 D1!H"!& H) {l<[)@ DR@̰5D蘱 Of71j]SL܄BWl!8`;ua&˪bqD|c2)0Ɇ+D$xN),HO = LM1GIpE?XĖD`>Ʉ,uY銊ϧ认 >h*ntJY4eAtD-hkE{J9=ZxI:9'sr9  yMuw xA{,e,t^: Inxc-iS!K!b̎bSRK ⪴4JA )o} yЛbMJZ_D?kd1B8eC I(D7;'2-??VTV6cz\_M"śdWO3!| {?"I5ߧUJ1Wa8@Wf~JD *hG?AH%2oD̀IT,F?a^ `K,!tXG2ffL JYd,♽G;kdTx7(u3:,YgsG3@3V)!1A"Q a#02Bq@R?:g"`p'Z#œd2VVJOksHh9|1$ʈDޑ. * ,䢄{Ki"%L!K;Đ&PG(g?&W%H]pa4/$Cv5,OJ,6AZ8Ӓ[&>΢PӁ~eAZj>OKG!Fe[,k#IQB6lr>2XćDĈPQpQL{ 8ԳL pIKv]jm%(%ƲeTgHe AD!9[s%BX"5Τ)zLc:%.Iv%x(Վ$}ՑbXڡ mC)ٜ6Ί.Clf/^Z$sb!!'z9$. "e YR=YJk,Ee{ &)[3L-C$"1E%Y d^,x(xfYrq2T5ld]Zr7h\t5 blǡ;XD!"S:zyrmS'ʲ˴)װe2 BױĐؗl"\!e 2bJqqVo':N*D.'z q"Wٍq(vLiI928!I-hB ppP%/Xp6ȢOvl^V r;%ظzjHŞbBvk9׬QHLtbv7GLc&g_uS.4䳹2Rv9D7"~Ȓ=d^9e49CZQhkSCI-KG:CNK!P.1"IHb3.Mwe |x5#=Y \lcLO._ rsGTY#b%-X:2Mb#2Iiv.E/rTYc҉$KMrCCPO:BKY.$'Y OLm\=[Җ0$L2ceY.ň},bzزHQ?dY99#$1)Q㌍"%rH1cr>+I5bG+Sq uzzaBG"Fq"Zd,j zF%~ai#NBnqU6ˁ~rm]z$:(LCr9H4KjAP%.D6H?d7(Fl:ؕ9.H$. .Ū. p'LPN;ؚV+p)G_&X. .(GpK&y,Q.d̋e{p}bLO)jbT\ 14bxqE"B|a 7 qJLp6_5OUB줒 DYEO#*b%NY (& ,)hKZSBY8>#)X1h|@mS!&xƱjEYk0SjV 2;8&Y\PC$VJK%lL#J-9QGX9HSLX2̝FyOhQj<HV 7zP@#:c%IPE4CIV3FdI"!L*$gE@'I)ԖζVAT(>:+P$#+W '6CY 3bb\ :&%TBKƎ id$̛?bw%rCX|MKFZ޼Dyx!P؝n)HVxeE!5hK!v,e&{K$J]1>5L6Gm֢= \nN ,[%+]I$:$HB,]-v֐ٖ%y2lYE $|}"p3ܾBC)rؠK_J%BtOG}5EIJ*XNG$Rl[ycvep)<|ȅE8bCdA+,zuE T @9c%p?j8DcZb1 Q$=1*Z $\~{dD(ZQZWD"6N#I)(غ|ؚ1|x6e33TЏ* 6Bid/GJv.ZzDzsʚCeDv_#JPɾH~ڡ%91ϩ- S,8-&K{O Ug$q(dZ$Ή66C-XgR|d9!$f3"2vȉBp9I!H!C(O#\DF\, ;Y G6#ˣbş8.MHԡ)D2 ċ _D*,^$bN9?ቸDijs#T}j9GEAX؞'ZH"^O#\ ƨhsGQ.pB%Dr2u 퍹zJK|%. C^~,EpTyIṙdE2.6Q(cOyBW9$ȒqY*?AХc*E2;g‡1Q2Y[oR-xr'ʓ9P$(Gg)mƜ<"Y=$L,|&GB̡'c"Ke<%)$Ũׇ%Ȅ> (\#VҟD߫9fԱ,9_Q{,p&iFȴsCG4&|*(-.d6%BZ.\"mjeBB)hsb_.u_ yC<=PEI$Ti JaHctSBN- ,#p]<1%-:.XPcjH!ٌKDZ?ġDʈ~i 7]m$B$%XdmKbz2OYS#3T ptpG$4B2|=] R??!r92͑-d}hɳ,ed5͋I,PAZ>IV1gkIPrK@E#bZBG(?j& uZ9 Cu_dI_ v)|U7Iq",d]#)xo|4OI$;,S͕f']5kO /ND \$˂D68?CH I)4YBoN9)~n4b\lx&Jph^_H0M\"-$D%ȠBP<O!tҕgM;c}X:PԘ+[Dp{ɌB'l>#'ƙR%e&g:9v'pdq"K#ZM H_K Lgfe<YfujJ<^HK Ջ'— l\ie%-%[Zs9<MA gGcrYG_ p=}Rc bU"_$V| 0Yd&RL7lx#~<M&^D!,x`&$")B vhXࠝ"^b .f̧pe>|xeA^@B x#Ņ˒VJwxl|@! CX^dsl~Ф>`f(pA+F[+$,! (x8cA+pk*ˇX`h&~b;{+C1?Z `X.CϘl0OLCL3߰QxX(HgT"l'LNOm|4H$>T>q)XwA"Pt M.$JdǎK˂t.!1cAV"Gn.KfjC. Bp?Ʉb!iw7}dO VK+$=͠.RkP\zHp&MMLX 0ay!@>0&,qϘe?uɹY]0K(JEI3e|D,*I3јa3{y,O Ŧ4ç+ZVc?P:j0$y]&ԯlX ,T\Hbxb>(Sٿut:MՖ.i %D'47qax{W!K!)b\CtCxA UMQZ&GI#(VH0]e %% !S/=)ybY)ʼnbض)g&#ఄ}W(GyHFY \&Y=38Bt;˂SJbGbaG9Ǻ T$^dD,tFZJKES?6Y0g6xN S`Sb!3'^BZ)')YeYg$(=rpY*(((LCec"i"O=-5'Ni!̲QYtD SM p5M EBg |$shˆcd}:DʄK ZhIآQ dGJ(񱴑46C& xHse#Gcr.8&[xʽ( uƏ"QG$'޴ȳdhm2opDL2(PBqDQ#XcI$[oJ!uI(9eHtF%X/Jcڛהt'%Ó= o,ٱݔ5J*ĚBMyE$5HLH<|X?ŶE'vAeUh;ChO$!lB! 趤O$p2/s>YZ\Ԑ{ȶTtCz\ lX*^APBCZY*O,I2%IFlV,('╢M"8BC\,ӓBI?-}id%pLX4F)zNL%'u9D19lǔR5"mJ*dDY4M`R!f,%$>L #Y+!(E&'GZScњƆբE6n[#mK;6!C,PN d)8|%+G%ZoObXưO=sd4loBm |pPI]hHOg?(*Ύ+Iw5D ^jU5pI)%- N>L,?dъqI<"Z7[c<'#iΞlBY֓'ƕCL$1i)4b1Ni9Q#|xy':NYOCPۡN#t]5c'[;<`e"90ВxLHXf.IZ~N06hq2e (u##Bk uHҁF 8<^s}x-$UZJHxc$ӛ0n$ؗ ENJE1r۳)J%hޤeP&HbG$:=E&zF8dp+mKXLbS%(Q&1ĩkD%ش잆r==< 4:!$cC!Wi?Gp99'Dt1ܜ1axǷhq.NCS|+lI֍)6䯭F{:7$9w3=F*(Fy)B2jǜB?2kkC-1j!.9|) j =Û(ӟZ!) l_8(X\ ?ce GJQ =2Kl*s2]ftc!ƝIt6g,r^zr9%~ :-,4mkHfI2DZ,8b(>'BLI*2mI%6GmP|1jr'# !AT6r9giz2([,Q,bQ &>E YVdEFI7^H]Ta1&ǵ2GFI4{cx((67ds:%LO\w:YĈlOZ$rJ*н 8ѧb1( rbͬz0Tp̞)Cp&xydF_&;Y P,6c!HrXƸ(! ~܍S@!22i= E({!H|;s)y'G$2s t6egF6<]T#% (G1$hy:$Ĕ%sFKbkK%^SBw#d4Kdر/q6ԙrxaHM-ŹecaEƦb)ɋS&;m KI=bbc&[LK%G?dM1G2.Gfte!(d)?BhZ9ΐLMQ%i<CAJD$dƋcP>xY0' D>89><_ <)jiM"IR'DZ$n&(vʲŶEؗ"u61uފ( \ ";,BT!7"iɎXK2@%'ӧ)(IQPYa> BynlIq=dsmR7țY8ѱj  $O%*1JgSi _(ٚ,| RHpLP+mfR9Sx&ڒ{2y} _hٹ~$BMD Z2NL$Tw֊,˂x)eEP'ZcI1;b]\kz[#X+lI pz?݃5G!4&ƌ}D "fYBβɮ͈*!Rs^ct/dx66)!ǚR5%-tB8cZ+e ֏:Xoʇ ƳYSX_yz'ޙ(ibu Z"7@TV[}2Uh&CQ/U;C($[۲&FG@(';;EҦe@trwgg9#rC~an-2*x^PJ}m$>>E@H$kCM_>{ZpE.́QsǗ!h?F1[SCȤޘz{z$$c [!eWp+b8 怒J`:\\<Ӝؿ/Ϗ 4&$iW !dWABUvu8a$*١ F $({ikB?ӯ(Ld.fE߷ 1gS-9wȜC 5m6eWs1E`,:;yK;<4!|{a+@&ݓ.ϙ=Qrʾ"6e0?U >K~n<;9ЂQ ï6gvߜ%Lx)Q^d#BȰe Owkٯ}n&lU~j MQ.=]^}4+Y{ P2j#syI JgIbe ۔ yH,1WcǮq0g֎<81#Z0t76eGS{j*>z5E{l i+]x>AC(;%ۃcAl800Ka OQDe|q9-籹" #Tv} ١%׬8hC#7>SoWQy3>X-,$p9  p ^bX ߨ?=s/tɼ~hƷZGوlag}**i'x*n,s;Qs="1a|6T]kj=04fXK69uEl|3y!.~VI{_aO)i>f`Us_SՔWX9@4qZێp/aZYH߹Tt+[P$CwXQc5OPlPJucmA`uE*R8ᖟ,p>'8"z2_ Vre *E4hm;csR6u%YFEIv z`u936 , $j4\R!A \!ZHG$Å Ϟj.>1M=A!9uZ o-A)Ay|Ni>QTDͤ v5P$7Wc% R *Vq'nNs뫅"̐15T>x= rPiē^ׇ h|!T|1Mh,VځxݷKCTYTJB>[t[@Ƀ127+֨++;߻Dm#P HY9ソXa^4,ȹ& '>]-9w т?s2-#&Rۗ4n. 'pLqUϮ G(Z2Cb:)&wͿi85bNOM[(?7VK#!,{ d23]\͊(')ߖ$(Baz*D|/.zmk,MXZ-1-\u' AWb\f(@&!3Z%#2(GFW;#BM{04%1s'Kc|R ?V9+PⒸ{(iTf|#^л=%AH(Z]皊tU TKxj[ܾVFsl[uJٸN92 ICœWKju 8H)zVŅ8]Cah ( mAmP?9_O}qӭ_,5ۋ#$-m/Ro n`D;9~g B`=]Eh?%O`nZʡ柖HO^bEy-\ĥ_xIʑ"EC,dV6UݬF.m0P)#P!>Ng{gkeZé_uc=ZU7EKU H{n4)qnga0Q[F4Hy.F ۵λc'93$8Ɍ> ň\󑑡23w )7V)LqV2= 1adSj>[(0^HYc'qq#߬4%FPS"]|M.YdJ~ 3\I,a+Un&yt- ((FIʵh|dX9(i}͍R3#f{,1_:~E^erdS"vIJVL.Udx|݀$)R:Vٴ!GZ G?I[FUeu)Y*e1 {ꂗ3ľ(o]|Xj[Ю.ꋛC_ꗏt;8jׯuއ^PQM= v M} Y e;ifExr!4܏,itF0͗-ؿ%JS+n7MV%ajK u$c‚i+ۑ$2J?d?B`8j18:^iǒ`Ah3/\k'DB|crK.9Dru!Me,WFw=Zz͸QjAȞ91GsiE/)Nr{lln PNIYF5!Ѝ-Ik>iE*Ic|a6SܥTV) 5\ LU3Y``B5/H~y7m͎#gH^ 7 nY!BBBr D ?åmo9;_gr9/x5ŬP|^ʾ!NR\{yFȽ*\|dSd$?7FM!JjS Nx\_frr./z_d (4bz߫ɷ3d. lN-m$KO.9UeH0r-;VέudOi0ÑHid?:/*s{NOFgof},&*6a Zώ'~Xb *|yA硢u&~ pSCi5xFkK&X7Wl[dxëWin`|v6گ.ckul ?SȤcXcÂ'ٔ= *|DH1\l4sf TYBr)P,Qd 5ذ OF`+iDXsw إ J؇(Sr>l=;چ+BN2н:-sGLf迁*intzy袅60Y YB.\u]@r c-㪋&%W -Bri!CDtJ/73'$ NUW64gqua $_pM>%21I*%WW|:TُT20-67\dPXs+\5 8ƢSxmeLqXE 3sryNM9n5q'#*W04H\r N7 pR\›}4.*|>ѽt@aɜ01Жr*0Z&ԲH9L6V\g^`: ƄH%J@&:rxZ.Y#&y[eQxC7\VF`틹eIA%nkeR:%S ůdv.yYaSn C:K:~]!4qXYO[˻EZ*^a/J_q1/k% 6}˾0dqe8Rϩ D3֌SY8 I <pXy=&#nꭢ"n6^z,eKZOQ@H굪3QXIY!Lĉjw"L e$hE2$R폇} ^63{QvUOika.@xv^W@p~ wj7=D̻iFiH;)6 =/$tIENDB`admin/builder/assets/img/instagram.png000064400000003647150515074560014055 0ustar00PNG  IHDR!!Wo pHYs  sRGBgAMA a$2hD0S, 6# d||1 }!i$}f(2H`EA0' P5'P7콗flrsg"c!Z^[?86y91.b!qp<.m ih,'Ig$< Q#2AH_QiAZ ׮'n<īZnO),AkC @H0A  YY.^ ⷏^_2,$>r(< c.H=|Ku RK-ٽ.4[\ [Gol_k6%þkÓ+0}Z#D!c] @a]ðBS.H~sSl72s Z{o?-칖sIȄG@$= v'TsBF*I6K)IZKg8#>f^ #r=Y9{9- (4p0CbV8p :Rtd~9=E갯νU8tPڨ ⻟+NuDɹzpXeӯ- x9Q|έ{ %s݋YNKOZ<kkOOelF8ܳ/dGg=ucN혵oẟ 5@VJ#5lϟtXc `VBo揟- #zd24e8KI 4fI3Ԇ>Wd3piӕVm =q?Ldu9=b>%n\Aa: yޫ= 7_wi~:3f ^%/g%Qw7 c;_9=hu%]g-q kZC8L?z󯧫TQ~W .PgD/S!=g@ l³G6;01u4,s$r;3af-35 >l 3SXhWA<x.PoeY&7(ыRIXZ 'ѪWػbBj׽y?VJYlHj0os;l~/ afc9QaSa9NVy V:l&-En>=ıIENDB`admin/builder/assets/img/albums.png000064400000001075150515074560013344 0ustar00PNG  IHDRNefPLTEkCpoîTq̹{ر|f(tRNSu~IDATx n@B  ]&ɒ.jL&B<WWX ,",",",",",",",ϢDjW{B:M,(Egda}rq2ZTȟ3,:+:Ȣ3 DJTcm #6QD;"7FctQ(-6p","GڦmD`8ND`8ND`8ND`8ND`8NDh\ҳhX%z8n|*l>N8JfQ":$:h2?eiJ",",",",",",",",",ow2$IENDB`admin/builder/assets/img/videos.png000064400000001014150515074560013343 0ustar00PNG  IHDRREBPLTECrOfZ[~Nݕ.{tRNS@?0wIDATxr0Fa-!Վ#`9;g7:J$$BI"$$BI"$$BI"$$B!u$II$I*I$IR%I$I$I$IZ'9!LCZBH1{C[BH>ϵ%t=NB:gQ6ԇB}iI!P,nR*BZ˄!oR}!7?/1@ʨG!M+Rw}fJ!:밤+4f7mRZ~RDR)</dѥĐSCj׭OS0aH9I$I$IJ$ITI$I*I$$BI"$$BI"$$BI"$$BI"tMxԊ<IENDB`admin/builder/assets/img/reviews.png000064400000003630150515074560013544 0ustar00PNG  IHDRP qPLTEOZe,h{Jwȴp;p;YiFIDATxA P !#> ui6[O#þcTz][9^Vq-;W-d;J 94Ng=J8^g`'lak-zl.Vj~㸵n5}I& P8"eVP6[ݢ)6p]5 [+̞ǁz{ܦ[;gAchyXyv+k@7t,`<11n.f`@_y?A<.T%I9x  ZcТ*Ⱥ<>Y_-.\/ߟϏ>ROD|+yΨb?ٿ$_ W%R&K7H;w Ҁчu^elhOv,a6nX y JvV1w^9̓?y[g37±>?ރ@e{߫T7F̟jhaz&BKqaa?߭nЗJ I8dNR|],rTу~~/`@uخ TUzs (0JwO~{0fu_Ż:=_ʷ"8KzG @&mޅ&c'R# cb0H |Dd\ۤEbDl-%i蒵 mx_AR ƭzQ3RjZju}րByQBLRld8\Zkh6 fHi*~L3,Pjڶ:B2bd zTq*y-6>uf4Ĺ,A?[?aN?ۓXMq(&ED<7_`> ^L\KuO[qD)~ rMQ%{>@.\ÿ@T<汷tIENDB`admin/builder/assets/img/user.png000064400000010752150515074560013041 0ustar00PNG  IHDRAAE pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxKl@3C3$-v`!).EU%PUm6   Mw E|ڤ.FEv 5ɑX%9hH0#PC5 MrT  3{t.TT_3gF#@8 2 7_NU7. \>~s,Jxx/g^oM@B%0h$ce^W \5?ui.Yt'!L4"whb21m?2'^<-%#!xsgq:{$ |hX6# |dn ~j'e6pOnk6'̕@HDRP(:J˅aH,(RO| .ߋ"S(D"9rH$,E2 ׯ_G4<~0D.e/ 8qx[+Jr666D""#bV愠I pA9zhCx<4x $I 77s' @6%q)|z^dssS$_S>QbݡNdjj>t] /f^DE###-GvI$loo>fe\.ghhUU)J" S-| B@4% #2HB BK= 1V @Q!dY\.$o^^&oe T*9X-gA8("-x^,bѶ\.keC: <L[zVWWIȲ+1ap ,s[:.]rj^8fp ~u:z~aa5SuVsjf\x˗/2333Awm+}SUZmܹsh8~gt]g~~x'ƷV+7 L&C8ftt6R,O}\ZZbii MPU% ƊUQ{\.B5 'APIENDB`admin/builder/assets/img/balloon.png000064400000002143150515074560013504 0ustar00PNG  IHDR )Tu+< pHYs  sRGBgAMA aIDATxX=LPs: ,k֠ Z AX:T*!i;B-JX.8׻8yq~{y{߽g.@+ PqWC*@ral8B;&tr K6O7l\!K,k"-Czj$h@M/>n2n)Oa Ix)A 8I`dPa&dc% 냈UÀWnvYJ,+ǀ Hbְsu -D"`dq!72R (/}XӑU . EI'HivvL\oh1nL Yr3\.Ū5TmT>iz^G%d$x\6B<{ ,{|1~`o7Kk%wz6k\Nq$ֹ5g~7?:o'BG"81 gA%%]Ck!:c]cҜ-6g,LjU)CB{oM,Ņ7^بOYՍek:V]x} 78;%JפM<';%CͭZEo,ơ6f&Q xL{t_=K_ړZ(~sL^2,GY ^B - 8+qF e};a ?AhǾB0za@s'"Juޅu3y|}xVp|ZH]8≠9PAz11s-;3h,w}`3Y+uD l;M["pLGtt(i=hD%1$QkL: u`BR:SW`  ~;?IENDB`admin/builder/assets/img/process-single-album.png000064400000004151150515074560016112 0ustar00PNG  IHDRRQvf+PLTE WX_~|uw[]d{}npx@?/uYYYD>C$IGd2kyVȐ{V˴^m~`fxx nDR4\D(܏Uɬ^yl>9T&!>ozÍi]*vQO )8d$E2'tI֡u]0Cb "%U]"oAWu)ס+Gb.!;b/Cb,C= ID]3 B῁.'-~L!%8[+E̐z` _/p/gKZ9!D돭rs7݇3TG`#2?7l׬A2_zd ' (~C M֯_q1 3fB~d 2aև3BTA0722#w=owgő$[2j5\Cp΂BR2| =#5ףM2$vh4^ڵk׬]3T'аaC <-ע>}42ĉ ЀAp8F"xnD"ѺCVZG56Ԫu,(;܅@(Pj ǀLРCxRdR(r.>gphh=e[d`diӎj?($XaD 悽' \ebkvk&#y1ak2Gck8Qrkwl܉- decDW,UyQͷ*k2LqAB[<͝|IENDB`admin/builder/assets/img/socialwall.png000064400000003177150515074560014220 0ustar00PNG  IHDRP qPLTE*e5*釤_7nyDvOFh衵zkbh设J,zDwߛĴ B$ve?>>B8'$EwY,唭y_Ԝ㛽{ 相D𚪟& |%_$Npob#aZ"ULTN}KKGTF!FWg鑢Ǎ$G@ana #&3S ʝde{*"SzQ~۝v,=GD{Dў{ {[euFIO"{/ opX߷Y46~d!= FP(Tڳ&r{loY% h\ߜB{jF #V'_n"""""AJժURJH'G7+Ԯg=~Eqg5vnea3g̒%˲+C]? EL1r A6cƌYDVPiaoڛ(.vȔ)T^}FO}gx:݅c;q* =V4OgV@(N)W(T*(>aBT^moViAi3gЃVBe&uV;0y%=QBe&7fT<.=lcej MorbyʴF_Sx 9E*>jTXz{Ń:fX޼@6Zk&Sv>rPf`sv9ZA dh0)0סB-[߾\VO\@e+SBrizf?fϞٴi.G _2Kb5kB]/ (IENDB`admin/builder/assets/img/events.png000064400000003424150515074560013365 0ustar00PNG  IHDRNePLTEOd+iyGꩍwɸȸ촜cp;ZYȴaVetRNS` T> IDATxko0ڜd$"Ahʝ!(em9LA/.OF}H~Q$(_/E"EH~Q$(_/E"EQˏmԅ#ږXuE 3=3uD=$&nv:!Z"nԷ~G)96WVtCH\%O;S-f1f3(V ~{6IT^#j1͓m"@-wX=+ qEߵʄ_x"Px4NlE,Tj1^MN]d(s"e_H!Z^/_->uUyL%iYwG@hIw"Z81rO\bDUy;Q}W_rgޡd!ruMѽk;h 1"AQվ 5Fu'ôo!pԁPj^zKD01#%U =OP\>}NuFf.FΏ";Sz oa ]qg2CxQ"u _DcߏZxwwSЍ1o`VoRk!i{ Y_êz` Dݰ?HTan >JԞZO0A#3d}DD{WcM̨ OdVBٞ\y!&hqjmyGa]Jžϯri:sX5un$&>Z}${(WD$F"< = IϽD/Ql:_#e|ݱHJ~Σawv|FSvG{*TTy$r75g6 a1AZfkK9Ks:;H7dDr 8#Gݶ]?/>#->.Toc4dJ6c!/&OCƾ37Hr""{_@LiV'jV&$ ZyDŽ 8#4,EIÑ{ǝ{i?.-o恲8du t"TlF*,!hrT)Wc5m®C  AHȶE6m%C<uj7cNC%dŃ ԪPIΘÎC\+sE GAnӍT7s?QJuT FJ<KTDWTXqfQmO \x*Eon,ߴc k5xL7.vM aY5h`84p/&†b->3ؑӁBX!.`X&X9q[6Hƈ&7mwZGcIkinJ.oM=M\a> c*Fɱx`A `2JN"y~4 vapOS% v\hެ؋eƦ-K|Ɵ]*<F}F}F}F}F}F}F}4 oIENDB`admin/builder/assets/img/wpforms.png000064400000002357150515074560013562 0ustar00PNG  IHDRr ߔ pHYs  sRGBgAMA aIDATxU]L[e~zá-hτu"d?)a&d ya40t;ѐ 3K65Y,5-?9=ӞSO16ܞ{}};C}!X.68kj-R2RBRRgI=̊z>&iKs\ ^6%%XnGb amSHi!d%1"<> Ř b"+ B:ʋtNKEZ-e r߫ԒrP[AD:$m =|3jxD/A%p`J\XW]{~龞 aG ȊеAj=HŽō~C#ʘyȑђ{d2<ˁ )!Vӽ>BٜEz5kW!|($+( ҏU%)n; *^H('Y.}OKPPK m-0NYxA|j6񘸾UHjaf![aAvAϽu<#ƪ绖 >358rjOcpzIO[ɲbYD"蟿!%;PRdUC'9W4Gv8]l&KXLM5A+g{3C'rkx LseDfm1bC3*>qkd0xuA7ơ߿w?<*G :~C7hQgyIENDB`admin/builder/assets/img/balloon-1.png000064400000003211150515074560013637 0ustar00PNG  IHDR/==90< pHYs  sRGBgAMA aIDATxZ=LG~o hKI\HXRDA#Y!EƖ’epHRL\v T쾼7w?3s|7oޛ@F >9phaj?B@&<Aug2+CFd"o7+Ƈ\ Bڪw[Fi1EDp _-(fP4qBnζoy2);]+q=fRZD\qEj>H-w(/(Ziw6G;[ =?Q"eC*cT\ !/r^(pi6iQ:wnȋ\.rU0kٳ$YUɡ\._,p*^o@^uRF=|+y( ;g~3@X*Y?Z^g0:cGG4?Kx'w4cR㙠%xqz /}Fd/0ݓdk%ucts?,q˸*aH\NMqTB4~o{ y z%O} k(3zubqK-Yr%T^!ҴۤëDl<1+_by2\Է5E#Gfx0hgg 8`\4 ,oY$\(rJ!@WyMGsǤ^˯uaՍEz> SC1$<ѡwD~ I2$1{H '^"GNR|$KFPDgR%asb *U0哒Xc0A}|lƐ!]Fu$ŋ~A^ON.~~%V#C5@t.sxqq[XϊKZ}q=p?k}!SI@F3iEjyp;Ks'luuh k_IƠPk{FuH ٕ1~KynG݊\PCDY-D>9􎖳(ݜuXBaY.-^_^im=1ozrM mvνJ{wq-K\F<8*4I-o)KENUL˴njiJc}wvZP\LwȹIj0%҇C!à~h!t+GA{w.T$:T5U8yod4TpM5)΁ʔJB:k=I]R*f)iIENDB`admin/builder/assets/img/process-error-fetch.png000064400000001214150515074560015750 0ustar00PNG  IHDR98GDP pHYs  sRGBgAMA a!IDATx9KADASy,<"Gha'6"6"?(TDK р'(*ZƝ%;yٙͼ0_!$,+<,t!u;qxN6f vܞTGሼI"*BX ,IKR%T`I*$I>G^aqi]]GՏť xJ^^Im@D^ 6!&'&@/$kjbXYINnemG "e%)'$8+X]YY1#)WW+LVPV&89X75t'kM]ᘋ/.o5#fXW:E?.OXŲtlSmLD~ʚNX]jU:9Zƕ57/c.M`T'*$r!ln=v΄K^\ݦ}W3j6ɺdCx*9IKR%T`I*$X Z<ێ@bAe! 8 WЙycIENDB`admin/builder/assets/img/ext-featuredpost.png000064400000004577150515074560015376 0ustar00PNG  IHDR+SPLTE ЬYFp6բìOѷﺚ\mQcKyC幔v?܏kgob x^o_u=0~dO# ۸wVcAm=4W'ۯسВhX,P+'tRNSÊ ` GG  H0@?p`ohPGyIDATxoAgĤ<zFiƘ 1@.Rz^$5vFvwYW3svb$\xr!5hVb9ƈ, "TN H I;0=Cb;2mV)F wECcOa!;N Pzh!%G.E%䭊LF(5ڲ"YV^Z&#"Y4t,-Ҁ0wg$+Fmؑ_(ɒWnIT#T fu$:gqO8L>@#sk,ӡk 썷>Z6QFqJט<7^E;[xW%q;:.0#Sz{|}?bRʱ |v,'.yHʥ7-O9bݓ Ui<+e?18Xp6yWgԵ]>!ugJ-|a*Ve{ oNE;#mW*2\pJs 5:s)w\Yr] 0c}lTzofNI4ҫm$i=KvI|QzJ;ѮTg*ȥs5jW?OB֙2נQP JP$%5h`P")!JJ"+MhJQ J%k(zJzGm1'ڊxC< YA5*^%C*)eHxD\j}{X^ɹJ"\X,vPR\S [>6꫖ UQBbR,D)3|\&jó+]%'(a*Bɍ7Ei$LW!S cEHFC嵵4(JCfeQ Ճ[-(~Dž\%?[}&,шX(,1'3OUQD2[$0 J~UV%_E Q;5yxG-8Ve RI=OQB-t_RUZY+o Q0Ji{!R׃6 @C!v hp^йߛd\Bs/#iaJ ̗&bkڶdflD'n\ X(*e $RBLv$^бoT(Amow#O'M%p{y#)õ>ekKoV0xnS s)9}.˘A{](-=&J|66tPD\JQRyhNG{Nu(cҥ_ SVߔʛSJsM) JI^뫣?0m%u Q3$*7=xN/=.cʝyF_ ~%8e*@ǔ۷܆a(JU=դMKqJ!0\/u T\jzVB"$tH#_@@b(jB"eHAPƍwh"do0I6(|)d+‡K0n<3q~[zsi>CY:͙x!9,Qq,[Y0CuAǸYP\SِeZ㐅!Y[4%7\9.A!ue<.>`h+͜U  )p$UC hOdJPrJ#" & +,afi.,5C(wq Q*{o:n< T,~2TBZ;Me6xj7J6=y-J_h?;e-%IENDB`admin/builder/assets/img/dummy-author.png000064400000005342150515074560014515 0ustar00PNG  IHDR22]sRGB, IDATXYiνݯ2o73h} qI4q2*QI\ SPS.QXB*ZZK˅BQGAP-ݯ== 3{wN33XcG%D vV1yC÷[c6o:m.uA+Jf潌#]LD{`T[UW{.B44c'$:=ycO䇆գҳ{>0bZqʞ/M.̜lKꆥ|{eQ<(".rM/KrqUw"zejA\d/9;:qM4/l3YW"GcBW+ Ǥ;KW+`(LK4䊏kU!|a ICښew^ D}L:;m곀5DyGuSmXQU&2r%?##u=vǚbVvm` y#ZH_mAs`XZA꒧Kt#Ŭ'+gν~ļwr3ɾ i0u= D"x Z(k*l->z `1AJW<"Ӝrywp]d,2988ȈDGE:W]lm21QK+UGH5ݺ x+E5nD6VH30ϵ*{gfX4zt*D2-2-^"RUj]3w.e;"P[ص)eYW^eߚ<<6I:^~#9fAm|;[.leBH]NueR %b̽0c".u *{E-v`0| e=" !-o8wS2M%O 14m㢭s&{_4љ&B:-NEVgLVBdۮ̽NK<̘'#biXDDzˎE:Vxku׾s_UZfޣ iFO@ @6XaQ<}4ƘJ'$J<-qT싌a  [ưe{GvIM_y~(:dϹ?+>0n"E{&H%4z]&BV @ uJ41d֥'r+Au$D]yt/c'!ۭXΔP]mYW[aZ\P!$&-cY,"#O0;O1=s`J'oU^y]ߊ7@ er3/s5YIhE$G Hپ2кܵɖQߺEoRߨB.u6;3YC $8AحS%ic'4zN)Rk9ZAFꔋkWv̽X{K$ HAVB5! RlNI{Vx2a5SunSP>0XaB߾9x#wJ":k(iR!yyIp=BBIǞ;ͅvisl jqx;{Z$|B2?k#bou_ +|Pە+-cv&Z40DvF oݵ+S<U. Rꮮ܌[ǟ^XQ*?~ȯf?^Zd&y>tWg2 &SCi@iut73.mUeID$Mvk\.f/-wܐ%MG6쾥񟝠9Fh@HjR{%U|˂Vuw}\~҂ H0LH{!V>}ؒ:yZflm3#@rug +UWIǎM1vB3'L @1>tqӮyWXh824sl.߭CN#±L06[fbޅǕ]mC>/?]E{_ y1`Tp)plC'9@uE~!.DCDN+"Gg{} % 9Jۿ{KIENDB`admin/builder/assets/img/onboarding-banner.jpg000064400000141714150515074560015447 0ustar00JFIF    %%2    %%2D9   Ԁ b*ɂFp C& a9$L$nAۘ9NZ\OOs=}jfc3$dP&4!emT䚻uG1~Wzs?b00fX3Bi~yW@ߛ~{t֔$*Tky~x]o~W~Ez&L ,X T3V1VFgBg 318o?/+~UzψyEgh} {Z$~-~qz_[\Zbɀ !L㑄%sXb)[_cYy8Ο|4?Mן?5ܙO_㗳x ٰYj#yDf3Z$fXHV1%xjr8{᛼w7|ȵW\3螹ۆb}o<='.͂wƵg F1[f!1 DN62%&2ZrsXDs b/_[Ϸ:~F2-NxGy'zoDf>ks<,LJQebQ%c2[RFef`̥"UYTkz1gOwϤ}?\!dʳUz/Vm|Ye,MpBeTLZpFJ%2 dӘRIVI"e"}|Ç{c⹸Sx+toů]͝&4j"3L #dSbҭq3ci2dq%VbDf'6)&$4IYD'5kz4yo1rf'Zo׭bj"EQj֭1LH5k *jʱSVM-V5ؚvSfڜ{S]lEmoo#3jU } -q>{_ɶxojOBMb}XNkũkRjLZ`HC Ugfj3$5l-E[|eMni4SjdM83~xV(4m@q k/JG.~ut-_NՋ꯮"-Jj!LzC.9Qve2H[arZ 4ٚl#m]bڵwShجHXzۣ W!tGt\Edԭk}EM 3LZVh#^3X͢Dɢ,/Vnv&3]6۵7gs]=6.-g>G07NJ&K&V+JXF"ߊ?Cg,[Q:鯦ɥKjVd֋QY^bͫm$bqYh̴̦K}jm+ri8M=6.T HyߪKd ׶g=SxGE?JÕ[ /9.]s|׉\eu(͏e:~pBk_N'Qm8_NtkEbj"-LZ15EN6XNb,.E4ٚZ*ڛMcWyrWn"ڳK`랝Vṱ 7't͞/>^Sbc]pmvϻwǢxM0גU}:[N2֭V֭֡jũ)UL8Jddő[f"vڵ6ڵ62WqM-Wzqn)n+}]}ί~_8~%tv1lDKw~_Ӓϛ]f=e iD2i#&qM}ZZ'Z-JuB$&'1jܮ»3Mni8-M٦ޚoN-6%-k5}}^s#=?Ex+~+8}#{zg&շYuL}˱XkَQ_*:$\L@4DMKԽ 1r/vΏELҚT䬮]VQ$XMu^fcf)JN=cޚ1ol{m6 w~D?I;?!Z?{o5xe=_CnuO𿸽M0d"t;yq:Uo1fԵet*J:ń,_-/vm+rbS~qwmy_#suJ~Z52fo\CW8/x^{{_ qk~W`a}Xpsi8~zۦ}3̳`QM\)5جbfqXNVvk]jo[-қJnN=ɦji __*w7:׿:{__u;--͝>s~.K¸W»br>5duCϟ8oH=>S1ٵ*We%im(LXlFʷr6!>__>U'??;:WuSax^/76>m/۝;y__f}(:ߔῚ_=>W´k N"nEK3Fq;qmfrw/w+z?7wCOtgsCwc^p! +[7IޕYDd"يNRl+u&U׿f_螤|4'-XY8.S;5~ˡ8^+wm+|ϱ%v`Ɏ7wN6=ӣ9H[k{5kJ5DiXad-lE؈+mm,Y};C{N_G̳X׫T^>;NX|q_'.#SrW[_̻vukɎRkQjJVU;.R؋/n  =ߤ vgjx^5sr=k⻫wn9W)<>kaZx.{N庯ԿjB􍢙HD,,ZZ˫[+lb^oQ=v 鞝w`|ͯ= gvP\п=yrJ0ypw57_?? 7+pq?7.!ӿ?;[V}]sLo-w=Cg{ޥ;;jn櫆w z_WW_̻ucL SUm\d!dVm:ُ7|׼q?E+tW6ÍT=_OyK^;G:oyO}5!ֳӳ]/|8 ظϛzוӋluv7zk'=KXׇdֵ< '{V򏱛CG蹛UU/ckV9iR)ԊDy2XX[eUY}k#2M?sozSzz}3߼:c4-ݸ'ߙ]xKG3u~^nS?xy9[;&~ї_֛<'avWiI#_H{+ۼ;ۜ~O0$! nԚb=cC/dz/A|Fkϖ7~Qrz\꿉Rfj.:)%\ZC6"X [Iű7Оethqݮ?sG?;{ǚq̺~cxƾ>]g'|oC~M>{_d{?[g{+knև;.'vƬrc\imUpfȋ-,I"Tqg7(x߻ǯc!~}Kmh˩0q옸L<~=FegCzޭ་zV[G}ҷ>|??|i6c&5/λ~q~P/-=gڝ|y+VN}#{oKއWn{?ȸ\_Rgԟ:8ڵYY !U4Y+!%.̕/ 9''gb/}>NcY?t[u:D| }x v}C;y@/_Pu`cy^><8:00000000000001Ձuǃx^yC(ށlqFlx̞qu&7> I/cC{{PEԕJ 33(,r [s1" ?Nj+/o##/#iZO>J2i qT#+U#Upu^3:GÏƊyv99Ø9㚌 Du|Fh>qD#c68 %_ؙ}˨F/}Ãpmxm#O˅!^xPus.[\U,RCR#;#_kYl;K2栭ő}G ^#a~Dt%ʹ%Oyy4! 1)e 8I6 ɅqӊF=HLi!E6FPVui ]E1+yJ,0n"$R_;I tɆe1=I,&Z%#?noZÞN @F/#1PQ#f: jfOTXa)m(-㍓&4O*VL=EЄffҍ rf;4$w # i)ZuW@ bz5rRDM hģ%pD "\4Duԗ2w/SE™\6ȃdHe"Ґ.<NehnӐ ]Dų7arqe%;Ϣ9nƎpƭx[D 4TԇMπdK*: :}QHN9mG<iun+WOzT'g{/ѕY]2>VeG RNuI ^2@)/>s{M|V].p"j$4HJ DI,J,*ZChVA}G>+'6K#NMs9p$Q'-nd2_a@^cuF()Yp8y0h{{R)Ie_K}w@|6xDL3dQ(pM6xP$A T vdn+; n#HW8lir䆺J[6+ud{O_Jsv+dDkKhQ v&\4*'L[;JH)#Ғ;JH)#Ғ;JH)"B-e}{䮧"rbȱO0n(EQcXeh:SV5Ĵk!Y| G30BYÔI/:ۉq,0dz\L<@3Q-mmr.J+Qk%:)i>3&+;ok}{䯦mFxi1r1) ~KHqMУp4Ĺ-v ?""Λm}<) Yd/3iYL['x̙3xfEW{]/4,lK*?4hҢ]/c! ɼM\o7 ]ө$wL@I (꾙4gD.K ɥP1 GI,tF3&;܃ו)Af0i1[6y NJ<9%'Riy6ToVi A\ܞZɪֹ)7pFwk ; PֶIRi$/zwuL\#O-/ IӓJRnWW2Q䚳BNgjɩ@q9VeC ; 9vN$eXkl6';SjY3ψ>Ƈ6?G&diD|=J1P ̯bn8iIS[vr f.5,vCcJOX|c &؁$d 6 NС@4Nu'HջIP?k| T J݇2YĢ3iw %o4IY$l"vNYly 5># }PiI6 IIz~ #Ђ 4Xy{2Ta+mV`Q 2UYLL@aɬp䳌RYJ)":[KWS%qxffI JMΪȒn:H&Җz?ficu2mByPm9!RpnI -᷈s!OZ~h͎]7k>;x=7 Q-D.S$ʳplp (3*.mǝ1͚#GoH;Ѩv%Gjf]7VEܹ4M8L$6Kk]n$ZS5ٻM3 , 5aqYC\rKƑhC/8O*mV`H[Q`Fyj̮ʔӑTis+CfVĤ)!^gRAJR\WF5g&, ʛ-B 2z8|3)C&rYTÏ8afu/,R<ȲG]6m'zQ8䦝 CkjۭiL?ia>0Um|̃nq *DhIA m+oj_N !1AQq "2Ba0@PRST#3br$C`c4s% ?tXn{fSڒG,IhduhQ20̚5:‚ l(0(7RL3BG^oSkDwE#|SE\"ܩi2I(I'Gw/w(r"BqpoЀpPv_N T8Ќg5Ă+mfDakl_Ɉ@:[{N&+lV î^"I Mεʲ2|74"M|, ,:(bwW~~8N H0J@6Jvr'@h֡>[؂#o(tГDs*A[ al3n/m!ߗ|z"XW/̭yh1a>%@[9AS) s:\VBug!'FD&!rOqƤ9Qb~={M %yz L w*s*Npyjxg/](TS(8;nAS9NZ # >e]zh23NY :V 3a" D T63O:Av}^g :VxMr.sl/I3$Qsz#塋?s{.a]h7Wni@P,CذUobT>,DذUobT>P,CذUobT>P,CذMgbC[mIB7Zy'=ئu#j{vj{vj{v>EDcLh^ 37C1+"sq޶i 9Zf{~qܳpN 8#psCs2< 0ThisJIY,?H Exv#B>}g4H:esQK 3C< y#=냢g wXՃ]3`uX4ڰslX8ڰy鳵`tڰ{lX<ڰy鷵`tڨ鷵`ojTgj,;V=6vzv x履YD̎t<(7ņ,2şM)47ailP0m2!&CH48T982EYt`^cHz68d@BlfmV >haN(buG{_щ3ҙLzS=) x0%[0Qkk7[)2OH`"Ck9&nY݋8ś8i͹NBcHzy-*U]LM]@5g AxrQ(6D1r&&Hl3 kig%E*57ωCI/q1PXVB`EYñC|J3b梘[&UI<9*()h,9Mi0ʆTԠakWԲ5og'D-/ 24c Hn|7ޞXz( LC8\NiL˨䟞M"q;br HTFxK8Ō`щР:k~*,;ZӟHBNeMnmH绑f 3Yڦ.pF/`ռ{8'ܡ4{bo5$34ӪDϡX.Z*s汽w,l4wxQ}v-&W,55w8*qy'>EuRqƔ6NiQ*s*_mV9'ot0_t)h;5g@"$]Bέ'_O:ط͹ 5+Fps"Q063 T<N3䝗8Vr7.0+Ľ4^Reuz_^S) ߖB6(p=Ly&GS"Z5_jUU}_j/\N)N)jog<a6THNQ̌Ďw V+?Z/ =ϕN=B<6 #HN3㿄nZ ,*NTؐMAk m ҈nɬ%IK:yL\FBBy$۱S"ȝ*hDIvXVvVߎՄ_8!aazFn287XZ0ppV<`ֳУ=uGOu3iXR4ɧ|NORt^j#Yrq8x`&LJj ,5ewWYfսTu'ÎrX酮mUqBwԏ s-w!C#<1LSxdRMci7 Cq)W֠?2z&hNe^zt'6!{}Ѽ=Q`U"[MmfԿ>|u.[| G<>`(y3#6:h@Ck9-UI> uZ6}ZX,!1AQaq 0@P`?!.kx@zb5bͤ J}X>^J 8"H"D$H"~! @T'xG I/@mBph#|`Uj'BA$H"Dcѐ! @C1?P*$a"D$H: @%A2%3~AǿD=marR'O=+DZh?͂d6D%J$H#$eF1 @CsD 1G0f1_ݏAn'hW55q>r̫T|r+ݠJ$ $H"DAЁ@ @(c^E v/eg̺O6PW3V/F!x>0@tg-Rk 9 x!Ҡ$F1cǣB!A O+p= O!F'tKмA[::M+G"YiT)J3N·ǡcB @P(X*1o4Ԃ5 n:TN];:/Nz2-m*.c+$/.lFX[3B: @*T8ed,5ģ4tE/ʉgJ1mbAKi&_Htl( e`ИHoI7]&/OAB!@=Z!W B LKb_9{Jœxdg.U-<KaKta_lǞh7{4cb 66'''ֳK%^ъ 98Lexi}gR!ϋ;c2'R=t )V&YQkqy#kg X*+p\B˪(.XXWnK:;謹V"mϼ:tܧ͊؋ƭMњvAHAc}RCO $W\D>&!ɹdʘF y ̰-2$Kw?d*q VǺv=ӱ{A}gRL[P c0Qw1s4 6X=۫>qKb@`_1Gt!tE_PbڝޙcQ{9 AKX:%OnK" :iVjTS‚Y;,Ĺ(ZzI]sĬSk <49KנqG/5 e|Π6B%jUٓUBwߏ~=ߏ~=zoBS5y3A :軴|_Ot337se Y&mJ ni WK*UQh㊸M iXpO -tHf:{ݙWÀ{wkcJy]H~'V/|gr73KvcPפhepp\:Rbc;$gynr dЈߠ^in.9lz>Ap%Bv2uMJsh'yY:6\GeP?c˖ddD,{nh=_ipWnnԄʘl[(0oX^*0B%e? /r+ԚhuwۅfJNkV\ Xb.@p5+jU~Nom#ƻ@3M 5*osOF=XHBXrb" nQ\I Zo!?mm(wWh@bEe5*]r̯ޏs~ ՗3+)}TFCWɔfŘ&CQȕ@O$}VP~yDkQ}ͥkor ^MU؛Q_`$BU1gye-b] 7$_xmM}t p_Ž;O;GX4NH3}f\ ANkTa T =?6uz$15ڴs+{e芆g 뚺M>QG Ó47E4Zӱ-P{/2Pa~oK}< n0 H$Odf  EʭUG(7Ak 5r?+sI~e`bi B"\v/ Zі1MrQ)kCu<]ks-ZMcph0Z:3ߞ)YtN0!FW07U8˶մ*`dionV%@ӆ9Mj\| |ʃr#BSbP?؟O#ѷ 4RPCR:mlj1b $sgīiEZuvWN\.GyWWw2/h:Z+0;Ǹ^EJ%yO55E.|MfWDj[F''OD''2!|~O)>|_GcYfes,.{Oj#f(COs:1N:g9-$kn+mIL[}E:seCU08W:C0ov>YwĽ U ZKotnӤh62y#N.߿2y5˩~Kь}gBgP0GVa\l 0Lp{L1wY2;X)e/(/'-#MK?]W8p]ć贠&>ɗʣ4x5whF7^W`ߴ㓯RM^^ Xp;b{n.[N~(' gx&I+5j "ƪ`oitpBKM{Yb8tD{Iki~2+_WIHNfX;He#Cc$Z9CN`+JwHKyI,1Tn:˫k]Eiݿ4撲nS-MPS{p=<(!Ayoe7[°, rP,֍n3 i UvQnbiVRnCyZRLi.W*s`6^5cC}{k4)5 tw\%LE\-Ҍ4k_TP  !1A"Q 024@Taqs5BPR#3C$S`bc%prD?7{X3=aUl׼3ƿwEM*Fk_4@$ hUoq,nQݷԥiݚi\7)?s;=JLDu`FO} ʸtҝzu|٣n0al&84Gph.&,Nnϵ`]òX_%cfa O:m?60@>Upz 'y;s^bpUHqeuJe+Ѵ7{]4*fEP<w:.>bf;6qX44 /习$;E)9j NhgtaXKI#^X b=o9G6+ t2((lVw/hp'd^Ã",PCeʯnZڱkʚ^{_#íX~- F=knAXvr: pBi}Lt(bC-'C$5]t |owC"rW9h?˰ܔ917>VULV. `ڠi|bϧgjӴ.nÃeYP^ZhEݽ[\j , :uW=&}[x X+KAUN EL a677άܜF'@07 *sЄ Gm{[(e%<},r V@q[+++++++q[n;pmeuuu~WW⺿* B8y75Bgu}w ;?+vhW\+vh;?+;?r_G.]p\+vh;?+vhWWxЮ]__BgR53Vke쨆9^O~Wo1?陖.|RONsoX͔gVW~qmvWWWWWGC9ꪸ3!bs\^n,RA.#Y#v\O)?U̮P[QZ-)c &wq,o{Xo`6y(x9\t:UOJn:xe)>(|}PpR_j؊asstrAtkH13F5fA ` |CMMCڢB`YN9'HVAoW/ul#Ltj9YpbdCPĮVrn Ph&^tn &o7B*#蛮 Cw[#}`s yMNrnQ `Rr}.7]oIhw% ArwfnT;ǴʗxR_*]C~KH{O|wi/.!?E$=T;ćʇxP_*C~CL{O|wi,; 'vৈ10'_T6#֗'滤)b~7R<<>g`xsɾ;90co62JtڦY(D5Q.ptnop\GݪF ݱ W 4:çʣ̊V۝ T=GxS\b6t ENFm#.ׁbĶ<`&"u r>0H;;rUm?M/yEǸY[ݡ CglU%\{: ecm --bN lWu1Y4hw+(X7PV hؚZ(kx]9;iMo/u+MR\(9r\(9r\(@~?zW/L=NJ@X]ʵ;PCbs+FtMq{3{.߷"uN7^jo}P$>ǐa4Dw,_m%UaVGT;SauN t\s^X6d{}c9VlSP5@ZGF1ܨOnMfkrTLãkM)3m%O`ck"HUmiGN3#wvmJ7P NJɢdh00vʉA)V glOk/O5;MQzqhYqYeMFFly(hߥϹMs6gnPH͎W)tZJ]pN7qLѻT4Svʌ0 kQ(4={Y,,jj|$BeK/+w݅QzxW /N=NJĠ,s<ߙ}7^c'nNɋ[rBψXxl-F:Ghv>-۽ŽY!}v~K\K\t93N+q0hN7B)!.176/ONZm07kb(@wZ?]n6w-\<#VFY5djɄEwr2eCv ]v8g˫uVgwW" FEx@t B~(;CW VSRhLIΦs!,Ýjc@`W܆>՝ #e x: dZTUJ$cA~8%56*,sJ\NsF%⩌MLZwq>Q֍e #Z1X`9)6WI%7cHRnr1X:?/tY5(rXu jLpOI+rt籠/O7W/L=Ljr٥/r'=f1<xUt0bqL݊vez FIL,;ho)w*w+± ms{U}6%xg'BW \+m.YJٲ(;- hAۚ0wrR_9Ip#|y{*h^l6nPї7]tB5.~ʃ<~+}v]f>_r!NMhز,#r\*$+v*7fmpSBvVH/]-'"9Oz2+Ø7VlⲲj72S]:L?RJ2_c[*}"łj QzxQ\#80*5f$P(${sZT6pإ,B'SԲ P>  ~8)sMñ'SNz5tm]Tѹ+N'w.*Cjr;ySD6jb.JꪷٻV#&UQ1~҆6^Zx<\9T='x;M"Gqzq'_3\mN-k|xR5r cyzyZWFq;wQzx齐h+};kb=Ԏ̹6dQ{T1˕ @ Utaz~ESSҫ#{N1uƼu[tc O?C]r t~`8 v/S)9p/BfI%q^9[(}İ8FjwA6m\!U x]%UX^vuU2D*Z`_:̴[~c JˮUX!XTI>Rs _BvI=&5s>' s =MOTe{`mX\ꦦ.dZh7N-\R/HvPy2ꨣ6n|b*.5UWb<˙ \*]T9g]{^8l"{3Hn* LE |{saD.gV`6cz18-pOי*dTE\"pmW{kcrx#u;(&t/(jZc{vr auI}>ebx OZq^_V89Xwt0H1\zi~ظ7AIT Ռ26Σ0Eu[\/|]ąqNòa8?[4!: t^ a&E,Ph<pWp~D2 1udpJlR75-\ 4D爉O?̝QGqW 3Q%dSVKkKj*i.ˡ>Mpg.k{l6,+ !xhW !1AQ "25@RUaqt#0BPTb3s$4S`crCD%6E?Gǐ LV^Ou?t9?mF Q.[܋pSS#b2 ?vww ;Ygid4~;y?\kVܘu/ͨMQ%oƱ⬎&|ܬ JǸ(m 4_ "mN*X']O,HԴ՛4ݻ<]&ZWrHG"MXcaG@2z5soX S$oc-#êcVG'в++D㹤(p"B?Xhwa,Z*挛q7܅ 6 aцS]>&=QۼSY;;w#M},(Zñ~?9n}Bա݇4s.0 2gXʨ)ͳzejs.U]3CݽSiul)(rY< Wb ;~oц3~hj(D~yC?lkB=$N#T\ ȥTQ5ܪۂ{k&Y.3| Z3)߹@]jEEW#ncGMGKn<-Zag,=.]3G~kvw/te5S;} g|OAl_)>]3~kjp=Iٜ?mZQg\] ܛ ݹШIe>L,苔20K NlWCX؏ߊk] c_b>~+k'ot11]о9>}v|WBϊ[] `>>+\wgt-OߊњI0E[5oָWg*]һ{B(\Cfhءh`ljd:ۦFvq dbp:(if{YVn(\amL3{W'V*9]py36Mİj#G۬&V9%-d7/n^uN:X׳-ayweφh 5|\J5{7b]5u Nlfn{_ݤvBo&w;O |R8t G#ѝ`UE1{XI5Mkw#M0) 8ӪoU0r "=l{L*Dֹ$F`o nLۂPVVO)G-?]b,S8ÎW\&B Q+ɽAG8y%MF 3>f) k-EDBl1٘0p>-m̚x\+M~;rV.;Lcj= D{!7;eNmtm)@o;Uarw%`C [Z3Y҄D8TPͩocʇ ؋ nOEP. -li=,X`PV]d_3'( e`.ʄg4iye-\ ux+Bj]AYX%a#X >t$puU I\M;gM<ܤU3*"DYmZͪ(r lܮBlYurdԒg$|aKSF ?n݁9ݕBtI~m&;Lcj=œh_w{ØO00L $BX.͆]n55|ZZSX/UM(4xQLuca{cc{MҞ#.c}GXڦX쑽{Ͳ!7aHYl̙2pcq5C-F.Dg9aU9MgUwm*S]xpc*$p ߵU(G6 K6=t-@u4FHI7sc<)Z%~o'wYl KO&V7Ό*m s"ݜ#czTG 9533J妔Qcջp Ưd69_nj->< ?&CKWŧeV7j,Ty$mtz1dwےkoFs= S7 Upevd| Jl}U}U}U}U}U}U}Tb1ÒʚQ Y7bSp'V9A{dUCMph1jhGIp#ҏ Dby;+]8xU (ƴ;uWJ(hީG(Xv)5ŝ>EcT=OKMë{AXQG~İr> 0i΋H#}uD5q2T?=53MQ=CA-q,M$1w (lmUrKݡsvNB%IqkzfWzV!Qϸ[ߩV L͡۩pwrҭ7Y/5NX{LU-.vȶ*B`E+Z 7X^y'ygcwPL*)js]^ylwǐ{9 D!7ñkWmv/\FZ4*#wpkz!ةй`BٚHC&fWc8 Ul/`껯qK_hx:QBcp:sl5 v9 '^7$FuM8w1ǿV PB >;'5Yn&15Nޏh]d9EI)9G yQFџkue,c=IǵQzjmE48֏i,ormޱ":`mUQS|Gʴ8&gklt6aɜq)IR8#vi|ɭ.6B83s1cCQ{D-NxsCӁ7wppN X~VO~KAR=7+/2JwaT5ĆRѝ01Mݲ0[ԏnnC3GJ簾w-#mڂ 9""Jy,@6VSJvRҢ61vfgfpvZ(o'dQܝ-x n\p)j.e=JsQRԾL3ڈ e&52T=uxm}=,53!#Ѓ糦:~Fp7w:RMa3ZH˗7(zlpT`N f `E;:A{[y־9Q+,uYMQV9mnBvS>R,kFo۱1]ڨcZ.TUy0D+ШնWSTz-.燾Y.d`; > *'}lobxl8tD5O7W'Nu\:,Kl&6X0xQgz؈~0⺞2FBɶ轮pvZ?UF{F^Ȧ3_S ]# %AiQ*AȜ EeDs(M%RSU-H7M8a<g)Vk7NǙ[󙤌GOea9 -d,XeE ~Lq:,VU@F~6CEIJuE#9U[&˩>[qBk+2h663N R):'\qlZsMZ?L=?BMKP͏u  MQDڭkyo‘ک! c^%Jʉ*TIS;l-T^%˖ˌI"Z 4 :Ҍ&eKw[%F1}CR+*W=ppbÆ%sX]ZFd[]bb?p<&5ԹgS!yJe<0W>sG_4. PUQl+%ضДN[2=;O1ʛVecj4T52|+\$ex&SFs7P.V=,xjSE>{o5 A] tҒYpX(?*x̧q]qRaF㌄vZ\noz@$( ?nv Ȩ Dĵs~7aC><*hpzZ, jrb1+*RpLBF&dĻ\Q&LRBjȪ! "އO!#bw&c)G|+5N8W";+{i3 G}GNХl %F*T_+D/%ZL RRp"x*X?mh[^q;%P۰}k2슮naQTI\Q*'˾1.J)AЊq|xHElv{Fae kA,kK8K\\8W!%D%NJz}paW+P8P x0Acow7Li+0`N^;FHDV%JTS+NM|NM*p8o1w%a^LO XaTa<'+|0~1g>5 T pp$>#_z97a8IRԬCUʁ E 8:xpi˱'q#}#0zc<<a%f$B',N*f<1+3 |q$H8IOiXmhV#,>Gide1$eqDHr+S\ @!(qNc6!2٧wWFtq=<.lx;9$LGUĉ\oè\ @8`{=Obۈ HƉ^S3DQX!~n ǃ.$HP A a9p) jRJ**.̜n1˧n ,T"[A\~]` $J /__1H1yx|k88CLrAقA(¿*J-R4Ti?((-ж~TT΃OʙDGN;BG?o!/*'#;B)9GaxS [33Ͼ_ϒ0ҹČ ͕0(fVfkW?GDTeG w[2ZUk겫HPxp__; <B P0AW+*1KFY͗ʠ#2QH|o3 3TĨaTV Bj8|{'<2@4ePNMD"^eko0i.ïbt}Y̫Ġ@JАuQ; 7T1xc|N ?0Xxu _l_Z4rucQKF+Jϴvb-C 촚'NzEImm0v*ٙ'ѺXaYvUZ/:@XV7mXרO_ߢq@Qj<<|(jܸi"D _)-ˡb+p4HVpZ#D즣I)XJKPL%km#l{oa Ieo| byAC3$80Dmcbo ˳X7+vJ1Ժr e')uѳtGng-^Ym)#># (}]zWn݂4haH5O*= d(2_{šn]0d9*{Dfu _cTHG-:,HHxCD톗QтenPy-B#աB.h.!feЪ@m3h~`x,~zYxLdII@S1$RA'}KZF - #ğqFO ( Q `Ԛ Wӳ y}3NTxIRa ``] [h.]Ph6x">W?g ԾNڙ1y0u \[2BXLvKC ıhrcIUaEe3-T:G%XxeO>iu;w0fbB/eEhX'ֺLG| x.Ȩ ϩG ]ʒ\":Ƣ%_W>To=|u]E\]XHbVyZVhGaFOkU㜉fa d"FQP }R wO]|kf'hUq=S@N=zoǾӴFgF^g>$I>HwΠTů. ?rFۇH+z Rx)+-?XV+;l6BD:4Ѹ iy5j6T*Tpn9E+N17CĨ 2Ji݈ `s(L,gHRÒpf74\f&`6#jXxܷ$̚ ΅n!:&1 Z5Vt0Gs#}< p98SAƈ`0aKj 86e4_AK =#AdEBuknB pD_s e$ 6EpktD@n}؇R Q{E(y C63Nq7;[Iq)u bMw87((}3]Ջ`gmFdz`ɨ3-6{+xE x|nG'?xKX[Y(h ]fYH.:=<_ipPdJ֬84=bTH^"&4Hey- EȡB01IR6{`(O؎퀆[~-M1;B;c$!RE[ٗhD5Z FZ.v  ;~[4lv[Nwɥe û@1/' _g51 wzq5)D1=E~qyJ)GЁ?tqx'K)F[FI pZš|W3-i8Rl);{UPɲdj1C"a3ereerDm` 1.ͣ Uэ ^TGq YbϢGK!RPowuWL!B3PhR䤋leڇ'Z4ĘΫPaH4o[ſy[ſy[ k&҈N D`4Ӑ(lT=ml٧Q,!2֯j,4)Ix^>Tbj5_!5:BcQr׻NyYhc&bYx͓aH^ڐR}0AΗ_H?QQ N1(!3J%9C*25߷99q.϶=x>B[_lu)zmTj(?V8'`K~)m$ED_@i[QBK(<^Y,E=J}Q-%U|~_ 6F(BMƆ~SСޭ;$fCPx#fAb)41ik銆{*-J(EKvAuHUP \@?W0޿":Z^0N6+S/@VdS`%.gy rgLsmȼN5qSp(ӏVmg S!K$iLB"t-Xk^v xP`a޶ؑcIvB&h4Q& ^Mcvq$,#b˜⦛)". ͐c0͌2!gh2s9gEp_=8wL˥Q̘.` 5Ah(0PQ!y㹩*f1 =[Kp,>03uZ~(h 9)q} 4ZʥH8Mtf#ze-y'h`\Ќ`Z![F/ՉlJ p.ºZ"<@ >ˮ(ہoH5 O!K/QX43 9foܶ~ m@'bNZsNOL)* OS/;"^P$h=;M?~g^@q7{j v~l,@7f_ڮ%& exFر{\8vDl>zi|6֟g^*tE0v8#1m{jRFiqn%cMu`S+@G2o..5=l-V m'~ dgS$8ҬPs.wA"%eYc HD4зdD(ٍAHScE(D^S Fª0{F,6h*.вD,-CeИ6 0ڴfHw z"חi[ϚQL0EAlP]*$MEqցomH&I gDk \vk 2orܟ?v)b\oJA6Qb[,!1A Qa0q@P`?l_[Md~b{`$.CRٗH;`e2*\b>׀~lB97oB 0/w`er?lGA,3@UvWQ_ b 1eȮmQؾX#FK&FR8у[1Q/tʕ*AUʏ-XR@]’eC}@;CJ5ǪG0ï4ȨA;JtSДD#1"fV:jShYϮJם)R*TLJꮃߧ:aos:z'׉]U*Q*TRGH42Xz=Jg0JJUt:Թh>+Kx'\i=*Qu Hosv[˛g0t0tBTOHc\ ],7e%%!E%=N/"눚V_BuaвK6a>>o7ϛg3|;>ϛgÿ3ߙ|>o/ϛe&l'K_2>tc6Q;LJҙOfSٔe=OfRz -0xW +_7"dWxTexMu*T6HtTOi7V&5~kNk}D`XW庍 }&JODyP5So]ev=!$Nju%vА:|zx::~'񟡱U'~hLit~r䳹< O琖w%K;,K;;%gr;BP&:+AzgW:T|bZDFmN^RLèً=!ɋ \Dnp,#<2M(h"=r=zCK%kOWXb_Rf5sjYk*> @Q XN9Sk\Gg1q뙍(^R:nCf{hR{Ŷfoa6HZɔr\t,ipi^45v5!z3c,ܲahlLlMF*3{ L)rOϼW~m}AxRA#"k0z*vhf\4:cΎm|e̝u 15k(lYQf@nY]cb;}PjfM_ɒbGَ\"ma?ޗ`\shj,r|fL*b0nxM[D^%EJlP.Ի#pn 1@1B%y'vLjCn: lR ^Za鴩ҧJ4h$jQ˃qvU# 3|;ˏ L˭M*_{^yo\D۴'LjGY 6C3==ސ.˜e8)%N /V)g S}3BCh}T fs gfOsbS9Lf,"M`&A, *ه׃l0W(,+Mw%H,sNqIDp=16ӒH;GV*%AVLJg mX U8|Vbb&e+i\rl#/)KQE#ѹo&`'G#o%&%2<1FƲC;$ p*_ uys D`b(TX)k0XZqhh7FɎ!1v#q hC l q. sn 76CSi4M4&&tX1[TA~Oy T'f*%0!D|(UQX3+S8).a>#(冭r .$,.*D2RpJ_t3Eá0cjF(*g[AbOF\D"\J"'19 dmm1Gyd6xU%˃w4+<7гae@ AlA@I%Tk NDT?@rwXO. 0M l,Je{k)J!oA `nox,VV,c/}O.t!#}9ӟ@h3Ex8""[Lb$F*Q8]\_HVXym6s"eov[cήTDG@-aF`Ϲ  L/߷ng0hExw:sV}aUBn܏iW Io!IJ^eb l"@ܒ灼]X _8O(E ބ' qֈ  Evą0/jR߆|l.zFڻ?ZG (%e >a'~pBEi32!<&Xφ>%!aR 1qaa p`b4LcPtD?ZfUyS ;c29-ZD G.!Pǃ87Cx'tvɨ(iULޣD|Z./pm1\ 2lfD!Z4q(w"=s];ܠL-) *\{(kXnaK YxE\O,v(UCtV)R٠ n߬/|?Ӳf{E.Zn1}Uˆ5YKe2!C$ 8MfJџZH|Dt-T6Vջڅ [p;S)XD!Uf|_nm\s,!1A Qaq0@Pѱ`?J[5I*n{lD%~R} }"L;nx~yXr=3ӎ{sh?&؟G'yaAhjhu[1eŋE,D}<\.,%B$1BB=e(^-n5="$/ |tmCAo@k>4^:.}Ōtu' /"mV1 ⢣$؈cG o2 !ydxjBh@ڮ]LX,XSA35.%b̷L  @x:M -xJ԰3ǠW*7@>.+%9;m-Y-FBLZX(0Hff_#ݥA^MEHrH*e\uYy-0#XLJU{owMk5td4M0@*{ěh݂shd!6c:8ȯiT#gzymF  ;KBkǴƞRA?{,ThEf8xKal$;2/ 2/ 2Ȗ+ozq4+} BD;X)|4YtMѐ.6 ˼@גq?f8hދtxUFV(= Orn4i`)~e U+IP:F`d17 :.ed.>3cAc#Բl@ƨ,d9$' cI|Q Be*'nZlyE,Xޥo-O- PA Y"*_Ʉ.a6 r`-/wķd !d}ǻbn¸.ʍJ;zVlx69%v\Őm piNa.C&&p$e;sTxfA,J|zN4>VA2!@vRwy>tV;u+"e]?{ 7zV̹4c`ӳ37EN/. K͗$s%4HE#%uup/V77X [ ?)k`(%A;_d|=dkQwlAlztI MR, u15GcDPFʔK]Ae52e{䧈dvsY* 77R_oؗD+@֘G-ko/5,,.^e+tTc7Qqu:[oF=&#TH&}Bmrxt ؠr3FEq 9xj(0q?O§ST*~iot%~e#MN-5`Ga\!) Q{ןw46,p6 774YdS/o$cSOgFO110׵@F "aۇ 0X&^SmmdX|YqD`Nu6GZX1ʋ|u,ĵp+aسp䨋BMFPLX>hG[׎1Φ&C}Nէvafk[(BјW.݄Q H;) sk Z)D,V9p\O{;[à\?˘Y\9Xs@.2pn3=3oHJKnpcVaT@22) v[-tbg5dT كV }W/e0|Bx=admin/builder/assets/img/ext-singlealbum.png000064400000034113150515074560015160 0ustar00PNG  IHDRE pHYs  sRGBgAMA a7IDATx}]eǕV9cOǺq<0#Y00yA!"#Dbd21"tld.i||w 2/ӎBB$t=׫х+UW+ZW+̧ԏ^I+ϷGl^y.t{{<$M{1aDI\@xY>AC˟|'2OI'xbGj?J{VZ[6dx4? eh 8&C+ W0(u0("V C&R._r8#iiaoR|as((Om1T^"$D:-2 B498րl G?ca3GLБ:cqg2.SʢKԽWmX{tqYf<Z3NL`Pҳ\b]Di͟s4ԋ+H9&QI3 #v) s3_vקu`N1: qݯA+WmG4SjC|2L+O%jR8rhqeYj(ϖzJ]M"O%,wCAL''?qaڏ.\pRČ)7ⶤ g0VgyFnLa d7֍3|\.}c0zR_\)&ā"3`.>{`~屝_>@ 0|Нܸ5x=v .YN1D&|Ikd*D+R^{5?4<,X x;vlǟ{7'NL~nA}ےjE)# р|QO}}K.1%}^p'35ٟ{E]CRE!i0Qg]vx$lsNo~{ڵo|+JSX*ӈDUN+`p ǝ:uj'q@킍/E+nsgB-L7aېW)]g0FƁZ{?2(ݶ^9K\6JnFPHSx/cF]5&;t1 9tm_0*h࿃NN΅QT$ܾB`D8e܂mI: Lr0I < 0BmY@pLSI Ƨ\({0;癱܌ZKnAE4\fq0ZH%dٳ'ĕƔ^m㜮X4bI<`m2FdIB˗/OΟ??y#GhGy.4-ݒ'I-}©S;Ӗ2 >ACE, \z?1A;69C &AE&CYt̙3$aSn\09}4+c'NHgoL)l~udC() `0+"[Stw7۳)X2pY)${7! S I(IJJ6#wL*44fA@{+!_Gi qA Ab `RVoFO;ҿIr00J)^@Mm"`LO>|/(RǑxwCCKB1 #A{#G0.5A"$JVp0"E۴`lP)osYIA%n)̧ Pc bR.J:˗/'>Vť)?1g W'4cH8\:Zqtm0.4+Iݯ˙ɬlXfpik' 9E=ܳ)b`0mZ1$-iER?~|¥bxČݜ[0n0J-5y_[[Gqā'x"-۰oxmWp% $LӊU\˛>jYl>j0BqA)Hijz7:{ݖ|Hqxh2>{2֔ve9r%LZ,M<90d6L`0F\i2K̃@+Lr Y`Ss0AiْKٟ?p[;ZTHvd:##!opJV3 +v.$ iK|/nޢu$|`0baM+c)V GuC,|˶ ڎMhQPݙRRf+v٭WD('&.0q C7{yϙ%:ܟ[eYO'y!z_r%>l$1?4pB.e֦{5۸W8bk)3¤tb͇OOb[-}40} "GpSxn}iPJV`)s&RLP<-7#]u[چ*-<XXĪ$U`";i"#ǏDVfjz9 a̠K+2F$XO7cOP{xp8{p)8{ tИAit|OOCC%4 #uÕ9kXH#yxN.~] Ǔ!]g IaTHP\s`:O+܍irHsi@,-ee`yU70 GM鸬BđBvYJ gq MLV # (_)A)j`4tR H7=g/bV+̟04Т,J,,-#@rH0 p{aU $ |Y[-t[ &N3 #3MI%M ~"&21n8t14I-S=L'}r :yj60ƃY(yv:V,1e*5H! q) aHo\خ`:f4iUًc8Ij>$Mr0F$Ԧ|BBVxw+f-`0iYpKOuD`)$iŌ,$)b9^{G`0 i5K}ȑ#Y`% ɼd{l)ە9`Xؕ -$EҟIūw:V+ ʔKJiK999a 2رc g47zb\I|B]v3.**$=ve:p-&]Q|hquƿ_9p|HBr9M+ 86 rVô\lޖ?H-#(YGI:t  IC*t١toW+s,eFV @Zd<_>M\H: |d9H?18,D]K[iN< 1e e[%Za8JGbrw-m˪Ei)ʤ?uMDZf`09z s.NM׀iV+}O IV8ڕILsHtx,VƯQ`xk7΁4~e>j h7p_)$aiqÖB#Af!8HbbH7*sC6$"aX, ZL{g40JV% dF P$ve21MSH 7rOŐD#2.>O{G`]"k @sm9)J?jC^(0{i)Ӧ85\+j q<'q AuɈO !B`Aoa2f?j@H2́⇾[ $p:SH #BP3j^Jm$)t}W.L+rIÈvVH%Ḑs %-y܉trIZх`08Z=Z ve⚾WBrĐ43ļ #BcCJʖ}%ɁW̱/2bܟCu$L+'.޻:[ wsv-:SnE$ Y&}{Qrt̞K;WߍG`^J%3qZ9-ebޠR>$'PHFN2`ng0l4#FP/o0A,"p]';l>MFEο._7Ct`oJLN_O'O[^ƙNcm;aYp*hHĂI=ە9:.+“n,u;t3 mWCR+W<$rGK= 0>˝9W~pK~w[%^Go&9>5BKz4´V+:ȮSt'7^ Lyd;w̙b`t߿} w_=jL(= V5=9_.i?^]wgv|z&^[g0bd )-K>^|GR^ <_Ȍ!V@;0?yN}Wt/swρǃ1RwpX2RAM>y-($ɦ:1{."̵kך%e _>?{O~˿V{>guASQjAq'ZV8sKBrS ,}闾=T4x+i8t:zRh]$xDO-!a+$d%)7M+RZaX t/? }O/6 Sv:s0Z%6m ZʌAry+5`Ϯ4W b>9nm1 .nL0E:)D+Ce`vs qKB:>H16c`^h6 C^$Se8cfy R&E럚. $=|pvNLu[F $$yb`tb7BzUJ WHjIAVVrq3蝏`LkPg. ەO.,il/mwv5 aM5#@#3I 0%Fw{+ZA_B>xu߼N;a8 I:'dtk?G'VP\^ݻ{7+$^X^<˿nU{tЌOg0NuWp-CcNGmr[ʤ?N;lNڋ~JK[ XX3C#xr 1tEL;m꾓w 0A9rAܽyh;}%C9í >o[HrKB2inE1[+ՊTۄdI*g/M |I I5E 3; syG<T -rvrK/2gIr8vX(C I3 OZJ˚i @>$G2Ĺyg0V(H=@Wpit3H@v }я: rhB _ˍWYгK=HBM?/^g0VLݣ_BԦRp),2;?#1|>o=Jq*n Eg*/ 8bR)#ӗhiy<4ZC( K %)>ONZ_tZi4KulɿDG32!1`tiuphCZIӾ)#qvh"ȑ#O<{Ca$z!4ەN4IH[Xz^ov[zMޥx%Z> p iJhL5GGtYm0\R"^aeÇoD)ƵݻwwU5,#Bʸ8 /j\XơNJeZ}eXE_FR^i0ΉWjֲSk;iTB??σ,092R2a&d!]5дSի>!_t ۾xSDN ϯKC~+I[ؒh孥o)PMh)FOV6.e83,.B׮ehrˏev`%V?⻳z GȮai5BʬRr?O)Voײ²Wo Z22u2her-tʡ)1 C_/1CJ*e-%"r> @K %e&4"d&VP04Iza*'((,锦^1 _2|#2hyk(!ۮ$Mi44)Mb"f+wJ:~.%iD6)oC.5ƥO2^F>4Njyim.!{{ yx\5|sC9$rɩS<8r??l-ۖ$ڴ_TS|Xkg^k,"ɶb; ukF3Tv f^V/hT Q<݈vdtsHB$_xҁYpDX7mQ1$r̙y,<.ii_ h7+ǯ%-yxD%@+*pf .<޲mT*;χ9R{/L'kZkJۉKeh}[yPihdB.#.<OE "07 `$V."6} MC ۀ\ٳ~PLR6 x i5[˯6J<cђ۫&C_"Vã:3L'/ /wr$x9RHƥ̎891Xy=h e<:icA)mއɱc|bzVTb0D%Y kl{-kk[ Rj,+MstS8h1+Cځǧx5 =Za /_N\j̈_}G~?#A|Є*EB.pdhhR=v߈:?o/++9䒒W ׸}AjaZZ-Z m_:4ICqM3=;6eKxZV`<^zۺA[__OJ$ i ϵ{"'NdǴ6,o>2]1>8JaxzW/W$#U4y&9>By\ZY;(pi#uJyrr"<ڊ$%F|ctt Z=92>,ItOoihK6/ i-!@rg?.K >Sj/lzP ]xGiC(AL5ϝ;YQG#);%=_kA +) [;;oKr`h؋Aq75!A'%iuڒ@NC :rWIzu)tO<׵fk|hi%Sq RZ*8jQ+O)>%R< oe\bU%EKىmIs-]K''O?xqXDV0.] $2Hiƙ3gv̑AGWʋ9B]Z,Ia 2^ڠ_ZJetշ֞<e<5,[sQ+7/;Wci;^~Ct{(,HWAG¶%Xs2d@81aޤ&Qzׂ)L)v;XOFI 0^,q~-ubTF=~RR,A- BmKmSjw`~DM3^I V$mHy`Պ~9$^ 8?$i$id\=| !](588ۢdԥ򭩽_zKט[tMU+Pk/y55ztӕڢ&,4%1;-!vy+t[Br蜼ͻb o8@"iI J{/wuWUSOۯ}kνo'C s{?XIR8x7ŗҮH*i Vf108eiuqNhiW m=;dVc2W";+< lΣ!t;~3$y(DQ0ɛs>P^T! nVrܐߓl<ۍTJKיr$<ۣ\o+l`m)-,aQ aq[&Bʶi2ـ]kqY~nt)֞_^{˾kV9^?Wa}I &ω.˃8;zsQ:\s,]m縉Or i@#ӟi$x &&ݣ`e)Su6u`my-S}Yu?ѧ9_Ϟ˝sⱺY~򣴌V`um6?vq]PIn3sY\!=8ϻ1S{ű6co߾4e~8?xƹs%8ҳǞ˖̜ЋdSJqD`PĹ(<$\O(9Aн@CWsgϞl!`ri%$t g|yCl$mjic> n#-Ni0AKZΥTI$,<u&1P]s.?VScvNΗeз%}:8,?Vx>N,?'ѥrP>o w>s)>0Wi_R\a2Jصk]S񘶰O׬(4oEf I)ˎdS""­BZ 㜾S9XUF‰8^q#튔]Y_4B|/*sMʦ"?(DWmR /+xAgoPi$ &X|Fz45szW[ډp]ǗmtD^Ha sp A7أ!4zWyv"׃f;ŵZLHrc?GFӁf?ϯGWT thy 5:ע aL4d{_j;us;x\$2umرc4>0^nL(q43wt{nA=i B0 "KL"QAl>n4 5LGcū5z-qzn {T?g|P`SQݨŃY˯S{km.^** K3,m~Y3sq1]h`TTb`Itgn й`0tqҫ4[ݕ{a9nwnk^->@Tݲ*֋l}c6ڼy~Y4sC`$-Lً+Lঐ1fŽ8fn8b@p[7Aq1&k<ϖG)[ۧF?W~,-@U D+6zz2Ijj=*–ٱ/&iBL9zL#*V&gnf 2/YN<\ېW:Ce2 ,3wY#glv~PR2lB~Jyc[LWRF{V'cO+9'2v h)N"N [2BεvMVNDԁ2jubsZr)}ǟ7>\hסzđ1-SVh,qX^; sw㢐S*pO[$'u2,S wVwùB۵X4:akRχ3iRjg;nipН(]>4&qS0¹YAʉD\_< eajyCa.(WpxpatEXtSoftwareAdobe ImageReadyqe<(iTXtXML:com.adobe.xmp OKHIDATx}]e^It$&MP)euײXV]uwu^@EDADD)!!! In7IHBHН.ͫ;wwdY`cZi>`cZi>`cZC>'pI`HaK/,\%97iA%q+Kk豙t9$%3s!c^_Gα׃Y%乨M._?#kdY{KY8S1񰉑^M!:+z_sd9%>i$ZMqf~6cROйΛϐ*!mTTf`.i$ې-P5 r't>B?Ea8efHA]Y8@h*bA4tNB(=WN)^drvanEAG'=‚"Ġg!nIC³zi/>WG3tvOMnx  8]9 OLMLe2m1z٣3\R U)8!!j$MY/y|>o :xTݔL( |O[5XoDga[u6DEk"\Ru\SkM) v[T[9ܕKY<%ן({%1-sMHԀvYxOp:N nzgF0}=n^CC5 3hKn:?:-c!%of7LyW^O%hd;"搶͟/l 4f]qsz*cARÂkt>Mg˴LNLnwf y=uJbQ垹]Y, ޅ6qJPu"[.荅0i>}ط/[Sc"I"lptn-A.:'Iߘ94(4!p "g@JqyLBJ\6  #qVk~ eH߾Շm `>\1j`ǀ~ wqgXer9> 7jgcc܏&+ٲLvС]8xp**jiCHpQ#'*\Vt.羍|_+sע2pA1=Aa_']dA"KȓVUE\:`- dXo!pX%~R8x= ǭ5N# &Lf&JҖk L75\g&L[HTՆL:AT :3 $HU @ibtny] n$}<ͰCo|^:T"kD}.G^W@TD LB2=J)6axb8G;1}/"l+;kRxlN`-m& -o(9D:a]&(H,f-G_hޥb Ptx<> =  W^لkepx?Gug+]p`ᛱx"bNLXuYHIن<.cp-ԡ:Bܩ3b>} n{9 wCN ?+5vMՒ'i~*)WU4YHGb?0n4O :Î~eYftrrb=:<ƒ](Q#OEs*0݉#0ѷ6N]0,]h!.\MXM_C>+@4{K>#GױmzX 7-WVm]ycH<!ЗE&G2ﶄFSc=Y|7}֭?fZ~620\p< G6J8`gw"0?HV^;X_q2|vtr&,2bjzV F^&l߾A3aZ"CP%zYq"d'I$ zc7choTKAT!3c'r-#K4 h /(v/ {"Z Tb(F)&`N4yU?qwFffxB,B]6%qf|R} 0` IcR1ލ!x3q ֔aeDӝX ڵ"b ~G|ȯRU?wxܴxo.75.AsY}\$$Hf[mba `$ދgp^80CKKTe0o۽[6ٳ6mB]]JKKɄh(d2)}ba>= Nzms88nNFBdB-C1rKD~;pǝ%9ޑs/mx+>Hx2 SUi4:B ;@ċ_p#M;1z `'гgD T-՟;J4Ր3O7|;yU{gυ;`ב';px@ֽ|"|8L&P($A-&Bb@++'P@-cQ@pNz'[ްeLpNᜥo;>@G"QAGe7}x`^o fs6طo3 Z.AeNw&3ǰ+Xиo ~j/`|\j4"9$?Me[ڊ*qzI!I8 6SBE+ 0ә,hTf~Ad(QF/E ==]K~Nᩑp#rۑ屡Q+ɝwvn /$Td$e{ʁMvSA;o_lQ]ލD!p>lP̉6Ar]ȗVC!KZ',V۰h %*/]l ({;I =[L[re$" J#Pj ` fFX@3v##DHq(L*3݇w7<ULTN \tTji~'$`/!z$*. ο Z{݀ي?><ǁv$] ,. ڪ!@w8Ƿ~A(P6P$RfћڃX.`FGp@'Y^ j>$Uad0J06ևBR!h; /SyXg?=pQs$:e ~b;@܎z¯,(·?؛?@'lCsq $\`퀽g?ށzR& U#1(˪D/ތXz>g98 ̦-)4S &:55ա 'Kᦠsyy#>(#e'? Q!`%Dp Ca&M]ELVJu+RaOnJkyA@,@@P·C(871S&"i2Y4b$o8R7OWcΟb?L̷%7am&?މϡ&ϰd; E`gY\[.Xk"t+$9(^9v4ZE.ϋkkpJGM 'b5{kƁE}YL84$D WȈQ@_{Byw){Ci+1q[Az޵PP ̃)#?[wnr yDdE&-x/Q_Z{D3ILvʼnWw ^AZlٲ\A?.jל}PUdy٪@[qjS>Eoop !a`LX9PL{[\%#HrM߯č/n[!0ԝR>HLW`K+VH@B( .} ֽcMh(#ȘgxAϐ gM~$uiFsݢ"߸q]M_ǚ%Q!4oE1vgqdsp ʝS`gFD?gO<Hg(" UE+nbx,Lg[iuMI*pe$B8_Ѓp5`9;`#-b(Kp) !q'@@6[hc:sNϖQ,z/-.eȄ.gTl~P 0cP f &E $tyQYlw?Kf_w]vACŽ`^B Yޕeh| 0"8%]DA"_*w2ѱKiDžM:ZG (<$Ʋ>E9Ead._`I WQ0`0 >9ikfWDAg"sT`)kD*y Y*t%q&q"B<&S_hlDJ(D[? ͓CUi^Qm$3S?@O#O١(ҎO4/Ŭ@CP 4]MvoלKIMJݳ$0Jvmp*-HH4zNTo.Ky)  x M<=GB *2з@`;xbMlЈ`:wyd"^DQɴ{6B - |LG#]6k_ްTڊ rUK@G4[ L41U>ff ĮQtgd9GbPi?] {H]K}Ll#`(xKX|-|*d"eVz]s!a֋Ib60K|iݩ))pBɢvpxI #$g"aCs2RBXl֠[PpEP;}A4|UYvdڧo} xpy.o֔PH3Ip3Ci"a?{}^97G ((Wt祈FEsQb&z&2cF}9|n/BA eb\4*BulќCa=(r/ ᒤx@m'I)JU.+31$a-陴\6hae\6Kņl>/v,˖BkN#aAq˸}I*T1޲ a"ʡAf*c-64@۞ڏқUBOBLdJzXډ>^CD{v+#pxRe-Y?3{$wng>T Xx9'B"N:2@z6B)LOYIܥyl,N`ǎ--82݀!FF000F<#ܚ$bRnl%DElg`wT{HN" ѣ"MSfjU2r3*mcl"S&@ ϗ~[[T[b֢T,O4Cׂ{ EZW;vs{CaG2ۓqAO=c(b""^ϱ[Vzn{ 9LFҕ." YGi%nCH;3CPȚQ\:A'  wBO9y^}D+iDj"'Z.\sJm&iT$T9ߝ> Xj=5&P\*!jC06=UoAY(IdbĤN2 6*s9NQ p)Uz["N[bpvB m+46!bDm5D` |vɍR{.8;: ߯~=: %ճH E#@ F#'VEzSƷ)AzH?,،_%d4AHf]/.96?y5E2x# iWD04Ѕzk"Ibvͦ#b4" 9|V.0yxn)cfCC1wz3 [LQ -.\6| QT/h?9&W,)Aۄ B9Z/H i)9W#ITW$<6,x+cn">Ġ`sbs)LJhi!{1 VG[CkTad3[1]{ _JIhPsB:KCpӒZ2}].OnA3TY!P1 %(!Sw >TWƼ֋_g⦛xT lb-#%Pw2KV:@L)h>=o0SՂ;Xޏk ;ى!B̋ ^,"Ȧ"]]qPܱFlۺUiT4}p ̂FmT]:=0UnhHΦ0 cMlZNEL%Ua wQ}]t;^Ķm[Ƚ<"-c#^)Q;V|wN0E%\E4;L>U,|*+gb_3ϊ^x) o1~\^r @ VfC(4,v39䬻 k;\޶&8\6QReVk?:Jeze7J3|{2h.;/啧}xKn%BS!3DD3pycuMν꣨nYȈL0?,!gA0P%VB~^UGiK?NppxtIXC/x&_V̳N0wزe %#Q2ILLh>`Im{bËkWb.1w7kF|Hۯ0}D'q}[Y7$+S擔zd-M*!䷝LҘs)c|mᏏui_)Ґ~4b++/fr8NyมaIBt:hk;/H$825Qrӕq`;[/ D',~'&b$,NZړz!7l5+HEM1n) *#bWEt]܂ydG^H*=Q,vo}$ %oh0 ~y'Ϟۊs=TZn ?|Õ?Ǣ[ EofN~nGjlqUC|X{$`[hZhX.wĥY!O \N=zKdq+% '3X|'RMTU]Ϣ{hN yҬkV@ksNMs$H8֭#s֝J&1u.8E$SN7PB@ڭ75CO#uri' a襯y?%Oal;Б/JTtnbcq$:Sbp]8ټtpOšmY9޶hoe˒O:ےըp'"ܾ?Eĩb gX4wAGsM@*o @M1X*; k_h]vŗATpDciY(XTy# g81mEKt̞5I$Oо.O'#*EDOT*[l'PkU*Tt-Ĥص&Z섐4tU~snqL |dN@,$Fy.S5t:S7|m}2՗B +Zh$Bl7E$SbRg'\VѤҒ2GG-܆'y|۳!)F_/ZOY{sf<|PX̓ceņp_Ur#=&^M0BIX}G%.r9 A bl.m闰2_N|?*~#}yqլsrO"4jإRm/`i3u|u[nڵGFI("4%*{;r/s6E0 /xK)5 #=PxwXV9F.!U<0AE N,_|{mI[E:|JVOpӗqK-$I !-ʷ2='*eɨ 7[Ҡ6ꀚhE \[?=d>/??sV.Yypm2Įq~92ɪ_h =ń 85(HAsbU_*XZy[iot@x@˹D-!-^ќ|R6c^sq-FQ^IW9t=1oLzstȉ˥~CbԘ(J]bV9[Q_]1%BxvH ]tC"TN񢅣-Y̞1cSPю[W~9?!.KƧߣL^bc'\JAXC2D+[9++̋.{-K"SV >dwdSR%l<@Vf۴X\[J^U֠aSG fcG\;vkޑSBRas8ϣgt_+\s'O< o 51ܥf8eȘX8nr՞b͆{]v$ u9RI pPjC 1P. A$E!a,9{6 W, CC, ُUBtQaV+g%IPV {8;T(۪hR"ߩ:pxsM[{צ?B!$ga`F0'9e*Z"ԋRm>q׮Vnoߏn)\䡮MX.48<^TWU w]ŒfQGgy;G ̺P8~!pw|8jjQH7 'L"jǣGͨH_N0 c"K\ U {OlG9iMܡ˥߾tu Wa]gNyDbBs< {0+ [S6ǫٚ#5VFG '>?;EҧUټ?Xa:HڜMZKaJmS%6/8oߜ!QD%,L8cX2Pd;j6+~,CB3?:XPl$9{CהeN.kU5g.fA+..ŕ a(. g[W-w[EyDȚa9I%lK`ʽ:7P?_ e7.$U9GƜNt,6 X|#]WK~.I~N뉒 ẗ́淐֏E"WD^ZK[g*?Ӫh xED Au nڿc%"> >#h%j, <'b$\,YŖ2n134W,pf/&? L:krB;ʛ4~C0uxGpDu!U'&96 Vb*U3IqbfUm_eg@nyYW+TS2*Ig4Qш#bκ;!J:UIJ]ȄVxJ,<5ۉT F3 PVAk2Mh #mcݖݼi"2ٻ 1~ c:*ccb7 c! 3?H1N)V0az'O!6 eUUe[Jk%{(~ߌ#:dͮIF/nͳkÇrc}F)',|:sV]J~ka BJ9+вd+ό"IDkiǪs$'sOP{OB0FE@7}g'>x"öiwɏ'_cb.%%X5!l9%cyq, ZN C8f[Z!Tz!/ GIg渚*RaJXΩ5PEZoGsf!4LkbhY#fĈPs~a%%n !n]L ?hvB]% {0oZ_GСص(QNdrY ݶ<'̹?pc,Ǝ lҌӇxïpyr!6V2HC / V@UId0hv^[Ih&2JaҐ,jOҨIwG}|(Ң4Y«P~>1 MaDDb fx=p ;/DR!o I5qu4rlPV bl=BQlkNy3c,m[dDh cx煽(,-F\PpgI8Y1+3_ I),I|!'/P՚wK|6ԭ)ʤ][ㄔOSJ&5ȝaM?,Nbi3>PΜ/"7c0t3Mz,w ?:׍K|=LW4PMnO&\"V5zeUɈ \Wt<i 7OT:*,cF?_߶mNJ$h%:F  E-,@og~wkfK$JwH 4fNt̓mO,B^'k|m Eө+eiSC*臞.E\&|@l&cdqz>K%O-92Ygyu=?g|ʤf<OK}c⫊r}<e AJU`41>k 8߆y\Xpa|%o*yaFM GmIZqZ@[>Zrۭ+*K /fmkŌ_8X/LВ+Krs#_}i6e7nuI[GQg8f1yIߟ;п<۰Dž[J"4P Y\]%fr WBa ,_=Y5Ek=饌\*JWQqV9V)4atѣ>(SD@eI}0ΨƫJ?b ;M|쁚/w_goN4@$|>'8fz2_~<>?Nd*E+.In@*΃QEMLЉEsqm湎%{\o+f2Z6n[ۻ' NJ/;z0=J|~ ʠ靻K>B͙W_3$I A Gc'8WD#@(p)մrͯh Vu|~-m]z{-aK7\s/t.kV -_޻.;JTwU1&|ggT:@hEF (Yᢔ~./ ѸlUǓ5ȤZ4&kȸ!bLH3[|`cZi>`cZi>`cZ 0 ,ɥ:&IENDB`admin/builder/assets/img/welcome-1.png000064400000003524150515074560013653 0ustar00PNG  IHDR~xPLTECI`rv߸fk~ٕ𭯹OTj~~Z`tZ_sGBStRNS_@?oO0~\=IDATh[v@Fh@">r 6Dv} y/T=ⓠQZy_﴾|i\ueY!Iq8;=sjp*)K b y n,I3~!^ڍ8 a\WaɘFD68)Y!vcOoGtDOH5K=}{g2"ɀjx@xPysoЏwO ߂~mlxgv*#\WLȹD9_GJ[Y*x z뽽mh|7 f&;qP!qC woi#cgc1Ww)THWo}Tãa_0Ǔ_a|̉aY4<{ }4#tGONCy~R;b&+Lskyqc#(f[ix.SB٨7 0bqH?,yݩ#وE/%};@Wq]Yɠ狺#\7MhR[6I_+uߤ^dmz61/+0/U_H_X:@t7/Nu!%Hh0 a w3HBug1V =DMw2.{VlG5 VTmpqݱ"DzVxϽ'Yw6jWޘ ]c]~x||Zl;@!uwɎjj.*xHjlLb8F1/`t Ywmx߲v%JZ`vwaxV C!0L#nݘ#D%5C;![RwwT}R)tG<Jݱ;TTMA񝘾#X AzvCA!$(;91߲>;g$M;4 #A#f&; O0i_HGb!t>B Amm53^wG!N#Dށ`)H2jyQcᕧ`6ǦQ-KߵeXqTmc UL=Q :#xxZi*b2Pm+*HQ+O/G ~=J9v <6e43$T8|]2;Y԰"f0<} H>;y GÈ ~wT5&S;3啝&T?wTZһhhxVVkl_dq#hM(VGSyjŋTHSL]'9CT^G:;yl\T['p_^IENDB`admin/builder/assets/img/success-banner.jpg000064400000026324150515074560014774 0ustar00JFIF !!1&""&18/-/8D==DVQVpp !!1&""&18/-/8D==DVQVppy!5 |0L@H) P$ !(XH(I$HA  3bKI+&@" vLrOy:6I" UbK Dcʏ/8YcuxXMI!AXBD,=CyѬʽ[w&l KZ-i-b+U*k3͝m>_g?=o[r{\MU6HAZZ\.tZXBA ݵ~WL{MjkS(qK>:KrI+-jJw?G+սN5\x_v2*8i(u?m9s\2Βҫ `Ad>lۧNR?H{_ V^k2x~.=^>xL\Yk&K}l1?&{E~mk꾞W?Yg.tV-K$%W['ݜ." (/\Le&YcTXKR̢{Y?=^ezf2*gB'Lnl׻|>ߩֽ?XeeIiOWg)Z鞘eŮa:w=>_se7YeXK^iSWU 2ƕ W-Xw?[6l<~uLS,fXeTeXK)DJηrq~ rλG' OG2VSh[~W蟗+1S<2M4]Esz^U+7~/S1p9~_tg[$Ζc7 Yg2e̦XK4ҵ'G7ܧވ.SO|>r/ݳeW{9[)q Y̩Ysf魚S.7vE_///-H+R<_Ⱦz?[d4,%yg2β2͒Yk/us~^^;΁WJ}WȣEjO:_o_W>c2,rr&TJM?Y;|C~Y~!jxc7,tk*%Wqw/ 93PWN#_()t9ye:KJdXG&?l|/s7a(}gb>(UJ{eZQ,I"Z aVf|fnnvCk݃}g)grҲKH&ʌ3F9L*"VL)U(gIi T 2&e8c6XB+eݦ)Rְ(L0SD- fzJԥb,JIH9Mi&RK EA`A@IS--5iIT b+q &VlMD",U"($ HQi"B",T(@52,$D,  $dH $$ID$   P( 0@Pp(8=vtOosf"""#DDDDD~ cco󘈀"#| >cSViI%ĒJ(yVj2I$QEu Jrs=555k39ϗ.A4cJjݚ$I$)DAki|_SɳQt=ȧ>z:YZ[|Y@dI$Q[Ǐ8p|>3O!HRc)I$DDDDqǏ#mϘ_=5/|n/#Ze49#&|j бj_<c2jE7Ne9"(ޑgxÖ?61#ۙpىbwC:"9n*/d@ܯgW L#,٨aEYE7aШs#9}o83}ږ5]sL:Txl}[bW#FO0&n'2шe 9m`z0%@JTUY$ & [I-9j s)3İi>d1FC1ɽ)-m(jǬ" Zr5zI19epobt Xɚ:VFXve"3i9KXno\]2j,5QV>V~+*4 xdNںFe 223I=ӭ븟u)}{H[5q/if%#l]Ľӭ븗uk{{Hs^?䭜븗+fHo^?䭛븗u}wNt6XlAW q-=*4#6у) *hvyn ը#Z>YV߃8ba4mA+ƌ?J|(^U~5g8OhYb Έf}0j8c" "d^ٵ-Z,9՝lɒ;Igd84(: CXAx,FdB|babXZQ@I5FnPj&o-/xVs ,@B|:<1[]O8HxBf@ k y[Ar$Hxʫ_.o!ˉ`d jK{urs u4Ḣ xxΗ9)P=±[!{(1Ƭ3kBWVzIqҔsoĐ)s2F4\_ʽJ>!}zl&(2Xv',@asGu?&Yl$cI$f@p"X'=K|❭OcRI\Kͦhp8gXE='rqN-w E&/#1r-H5{6Ż+9C!,NV nUI9I<+#䎧apo) FP c0AʶY۴tQP5t C $:O,l;bU*,L* +(vK;dĒI?K8eK.[~Y3ɩ5n,jčXAyg۾AI*:a׷X}UFrD[5/-_¶J^|,5l鷸OFcX\Xewt&6G1WWӿ-w#i zuZlG05"I)aRNeg?n&`3Y[.7Co15}#`XT⮀X!{BdvS&IsNy *K K$O W$TVO:&6"L7=jAәZ66n]I Jضg8]\)_-o r:taMηӶ.%Q3v#>2Z'lM<6i.G=Ocs%utD>'n`fI.,14&Eht̀#N`0`!5m{nޢ/oGVTp5mGVTp5kVXp5iVXp5iVXp5iVTp5mGVPp5<$2KJrF %o($j>`MbF _=!$ |] ^^ m^V+&^yӖY%B&_]t wǾ~_}@ 5NI?b,aX--!̑QW%g8בW>G`oe7t/44d=O |->?qHS>9 :tJxfHA{oZ d||~?q" l3 l΁<:._^a88Yfy,*l' 3N5{n $쀒xGQjg8`9 oCEO\M]pa< %BrDO;8%svZcI<{R $9[]yJT>yz/t?;LbAv<_>H?orfP9PG&DѳxXtc=y+ En}4:gW>'W>'W'W'W'W'W'[A;NR)#(5K84Tp,UZa\jjj W/8ψ8jiXdD|nﺀ\}ᠯ=y,[uel' _E |5;@ !013QAqr 4@Rabs"#$2BSCpc?.)Ѣ8=A@\mvޣNͬSMK Jpob{m{)&^WømjZ ~wJpDM T 6 ^ &:IM=X׷6Uż ABn6qM%881E-lB4'W2J5YWw9ᙪv!.-f~!gȯ LG15Bס ~3_ ~3_ ~3_ ~3^/ B$GÈւQn"п,D| Y_.H}GVEEyk 6O . d2WFqa>V{XÒ0ō. 4?x9戆 ?djsW{m!8U9 6~q#5%i"PꁡW+5x90>ȑ 6UkÄNsQRM*iSZ80KHλur*X p]ѿ]ѿV;(qf kN7A ^+g t툱 F¥ ^)g|r4 t6js]3.+ơ7,Z`b[Z DJ4W=Nl!ķ,^,'Vns`,Hѫmo`DTp(N#+<;wJG?x l`AQb6w+ 2䍗r(i:KtJz#T$]Q }]ZQ;A QLv=簡ķLZ^Q*7SCaẙ U8P[w-9D4kT $|UV[w-0ma4H'>,qB<Orȩ&+ 袢FmYEe&#a ^'g|ra[D,! ^%g|rQ |)a{Qa N39iM)ihV,1~j-;㗉A8H6P! X[@4F&@cji!RIRC+گj)2Գm ^-g iV& 5xr(4Z8GhUqV(J}/IeR㰂G0ޑr*Oi<V.f-g!^U^U^UHZ4K HzTf.Y*ߒ-Dqcr%QA%9b,xgl0#HFEN(?HèŒl7"6Ke4k !VUj Ak !QQQQQQQC]MTTTTTT@!w? !0 13Qs4ABRSaqr"#$2@bcp?VGxdUM8`?mD͏C SW9Gکmev1{&?;o}dϓE9Is82{H@UGO~\Si2wWE-e)ds6(e{Z9?S;4>ٰf\ak{L-{|1- PYYr7&tkZ%p>N^w }(dG&E ?Y7x/QɻxM>⣉]o.C9_%ƕ1/F]9/7}R0+uqn@ڜ:]^!7x6Y184M҃VTBnij5L.8t7WLJ"dn>Z %M!g|ڋD>:+xF.Pj12(͜bh˓ ^ٜYj8+cLǵqG@]3i  lW܊_j\)X #@ 0.;!y>@wuyFVG흼 ;'lhbu,S7oS;,!*Q&j[p࣠!:wgE15RxX$_hDt7ONU!Xt\"S]by׊(n044V3VB=re+uN>$t7WL`Y~NuutYk*} ?S1p[jd{jdZR=b s)} ^n0?J_Tڒ֬Lks{ritwf q>!f[.kTr}5𔚖l'_V'M ɢ[jOvK,9Ad/r:@~,zl# GZKƸd_aptzUNe,9DQ &N~2i , "d[ٌ'Q Jf M3G z0)aiuyD=4,}u1hVմ:sgE{[7.)躒Hΐ|DO9"v7E:@xhsU87X?|:j<8]Ը'њ*H e8@уU,S);nT=] 8z:S* Ҫfe "jJVg!:zTx'c/; 7SW^}LxɜNMnaqn㚏5755A I%G6_chf `ŵXvW}' |^L8T sFX>PAYX8,$fԝW(GԊ<_–=;J S?</BdYT0e.#?i&Sط{" œҊ-y J" 3Cá2^=1SL $oxh,dڲq^x8]ZhDW0 m9ٱ +z .hbIpmC]_DBm쯅|'nDh${ru$y-8t CtemݘS:pgZq1Wu$06@54 Լ/ APf} TԌµW}3W q!i4_8$I/X@ Yb:H+ɪ' KI%DܺڃPi!4Y@nPU?`}INp9l]\o"[(;gvBOf hO:ٷm*\<݁KCۭ(qUѲz^8Hi$ 'lD,;,AA' 5͟|?kQ'YnCMi|\X&eO :Ɗ~ã:aYTc5K _Ivnk릅w깓G|3rQ~􋜵#nU50-j,0`Pֶv/-y 烪IENDB`admin/builder/assets/img/seedprod.png000064400000007156150515074560013674 0ustar00PNG  IHDRgAMA asRGBRPLTE]3<3'ԃ[u[yy7 ox qHOftg,ƒ!f?pgdS(LqAA۷ݺu,,ߑJ9M"<-9842"2rn"Awoߛ<9Q5>+Dn_\PX#$<"| [[zee%%%$?NןLbmqҭ(4Z; BOO7f/(yHa՗b%=mdDL|,PN 1Ic['Jϟmw{t)/ pYVoK>`@ ̏K .s][2ڢ UDОK2gE9(_ n${vwAN1-rX< >@wm'7x2_@-s~,8G{+. Dۊ`v_1|h+<XhߧRDs $z0'2ЏXÕB:ɟSU]r~/ y}S Dˡ9AB7ScPˣt+>,f :V kL7W : Ut~@7bF A4G'ůD?`[C0p*LԹǛ4v,{؍79Hѓ(D-T[AE@Uq!ۆ=WnVp:YNC ?ZCu͔~ɗ B4ן14}k$ 6BC^HHLG9|4ޛ jcxpch%X??'+ÊtDY_n@kH~??˲zH=#h@`T>p\1}G}+?!{?#C!A郊n0`6Pߓq睊2Uũ.lQ*znlEh3==og?~,1$2zj, gr/%o0?82gg Z:?P]/wU>zB~ȹcP?/{ OG/ 51<{VN?^@o:EW&GCt)=͙7<E&Hp-+E] P%%#I" pkO ࿨<8n?KxNW H71b>?ps'՛'o%$jmFF c T ȏH ɯ<~g bs&vu" Ĭ5~/e%TїL%Eˮ8׫dbZ 5Xkc KpWUCOlGYXGU =%y0ke ,Md" KUkȁClfP@~2Zg ,ºI !W\9kȹPr_f↹!V vd \ Rkk@ϯ,Z۔#mV]X@@aA 6KA #0V?&+al[0}k f{Vĸ2 ltdY4z(:s*RVbEBW\-֯ RCr.$Ei]e (;^'HͦJuRg7爤!$&2NGp_MkpehlTaJ0oPa0`FJ1Pc"@ȇȐYɨӰ1;mh I!;Ryٰe*Cb SLȎCښ5Y%ZӈϬ&<6r26 rpcFW((˲܍0,RcՆ ʿ`E raW+*+CH} V`_ț] :TiJ>lgXkќi_q;ϝa6\9Wc, ;X!\gF*hSb ,u1~4[V/@,0 &ޤPXM, 5VRnNJC&90*uN>!*[Z+݁B|X;CR^o' ,{$dWkHBn&[("AexZN:xix^b.qwZAX%yϸ(9M$ V oT+?jHWnjBqNHyK!1e/ӛx.CkXqqt8UU g}PPxFd`-K1iũF#k/fDLNgin%WS硆P6+X qWmW~,f!f<G54{v=M{Ը9<ڼ`n;QuW3mBӋQg xIENDB`admin/builder/assets/img/ext-reviews.png000064400000006727150515074560014354 0ustar00PNG  IHDRPLTE///oooYFOգ_×ˋh?{JςtcQZ0ȴtxhm]p;e,oOۢЗŀwYQtRNS  * IDATx\0K9BQ nծ znRgjy|Lt*9*ל)@)s|! co41*JX4ǐ,t*L7{Jyj (EXe:!lTRBQڛ D;T,{F3 p46njgLLs ݿ۝4ދX}bN͉Z~FDB g !4} ŃNCv PZBJ)s#pp~ӀB4DJ$G_Fڦ(#Z.˫h`5v)9%[JʉuټjIJD!.7˚BmH'wc |pQTrJ- RzX.}{zuyQTL vڡR|yMSAk,ZGB=JBU 29BNCM< e<)v+u}moBJd3P IGr2bV@#HJAD>exYJ&}*ZxT+eTjrx< B\W:mztH/:x,HiZI /^z +Ї8)̿8I Hdx=IGF)\"6P+_e9 r^(Rx'gR3xr++ tS*ru*RY:R1fJ `5—3=.a?˥XP"(f&.%_F,a/]!1 啾n8^w{L߉`n"O4#!d组A/: U4f0Dߓ1'j9щI(fn, N>)t @3 "T"t `D1Eq5.\PO5ABX{񢪩ҀTʓ* umS )[_4kWM+~Jj(Rο[U71/lHJ&^fm]M\Rҩ9"=[xVT~{T)*Q #Y=jOJxNiT)Dei6)~q4Tl4׮T64?=yksi*pZ3î1"(^9CMS~tw~R>@?R*(<^@MSCX*uѐSiI}*ua,X#5/Aa/-),bvd/_7E733*q%(!A5Qd{#|}~81Pz-~jze2Sd~M+L丢8xy!(>F" S>"0ƇC'AT6\4t /|WHF`@S,\T p ܣ 'I$1 z#9eWn;Ը|o a t5aL)ݦJ$:D,XwXV%j+`{*u1U/K{^\9U'knso}9(1.]W&VLƕKCGM3Ov(135Ws-_z;Rœ-ȁجl鼳.n׾~}N21Ж&lYS:< a-K%XA [J<O`@7mwJ3kWa tq@@8 uԵM^k)m9O)MxzՎHC%7e6 nz/F y*W b]Dk@R7Q5`wwg 3,:HUu{ZSh⤀Iľ YOk\k`lҢ( `H\f"`0`uEmuq*B=Z?P~f'z`V#Ni V+SDIzyǩ`FMu9Iu{91&Mm C-Uu FYѐ>{!ST5)"FDϑQ)C:}_[b4a+<>Na4O=_ĖaJ杢LE9'\ARC]J)S%EީfЦ!\E;=>(SQ4;`VE&?` tST褱2)Cpjܮ"YOUSeMa^Xs"T5֥Wة>y.֒PdDk |I֮F `- ~ U<b{o`xS|,#~yk7aQf';-h!"$`@@b°YKl4 $}- aj@lޖ>hYB ҃Y=Q )!A6s=Q) }\{mBcTy-a*0oh*l9FÞ"#OTķyŖ}CqT="#!:retl}PGpQ9񑡕Mc4"jTUM$#^)32#Ggx&+Hr>ѷef/W  EFW_%TMM ؽ}t#졒?[GT-2U ̰:Lu|DFZ@ Rd)>>n$#ZggQu,hsbN{H\j#fXCDZ[nnj1g#L8\\ܝl]+$'|{!>}Ho4kEjd@_#!& V: ȷ|S{֐y]^ĉBl@񧝳[0B\UNuPwUԨ\01B\.w)sDB̡(,Q1=t5eǘꚛN՝sLb%&23*.:68cz>&Hn豻+1.k+i;)uuG>!lbZBȪӋU# R.-;Պ%۩"8Q\JCr~ ڠ_YG渌8칢@/bJMO^)u}~VyZAMc#e8E-= -_A~?ݏ~ admin/builder/assets/img/more-feeds.png000064400000022074150515074560014111 0ustar00PNG  IHDROMPLTEﭭ""ìȲ͸䷽ݼоwt菮rXN__AAyޅoT;CA롾]2I IDATxڼIPg5V4w(ht>;$YI cc: S{ KLTcwyDj)|bֵIfg(*"P鵨#ryV,3Bw4^ĺJ|ܜ:tʙiתLKdHؘ JYJ%LYb8{y{w_s7kTm4\˳gl1(ԧտ&8^LRp P*2D#zRtQQ{x1L9b$)1ғazl)+ng#Y/mۆ).0z">KϳcJބLHVS)@@B )N[QHPʹM~$D,i6ǩu4>kFsܘn7)眶 M5]7JUy%q>9 đ{ޫ'%h0uA-z\ `j=Lϥ|6ÑY[mOg%F˭'YV_LuM)q #=kNH܀QI^' \^ϰԀ)LֈҥxohSET'r=Ӛ}ZumuӠ%wɩ5⹔'(Rn!|,'a 2pS4E⑋'oh)ɔ/3V➨\X&JivO$h)oh'󻠙S (]|2N0:72)V_Z 'ޫS /1m]-=֩|=q"gRg{&H€(Noz!hᄧMƔ98PH rczǫO_߾**=fx+>|aXfuy%JXopշK↔<E8fxIVoݺz5IHM&Ę+էDfy0iyq5fXO:W1@g>NWOp)=Q˂ -S#.x0Ι9oE,Txf&QM٠<ƳCBQ>E4ch^Hyc ֩s-:zq~.u*'K}^_T5D1ҳ[so6᫟N݇gf0:"›n --.@ŠEEBJ4hz!h̖5obtQF U}sCx#qn[~vE;-3ز:LC,{6ϖmk^ig6˽5G'b&ׄ'6;ן^c;M%9g˰i?t©n?b*'.>ٲvZhN#ک6Lf)gߴ:SI}"Д8]w:Lr2K<ӒHGU}"KJ<؅&ㄧok4bzДy"Ӫ"8YyZo#s$/])gIjWȜk\qxNms;w1jI$iiOBqYCk=>K\lL7ZdM iL~[vi'_Dݫh'8UzZ$iku"_q'%3nK>}&4 t{`r>I:Nյπ"ώgH,鎾wG9oY\ŋVGk;U5lj&/.4yDNjTslέ2խrއMxjӧ)8qP28g-*Mj>GqrqQ^(z6'kǏA=MDDzOd%E>m晴 s<- Ɲ]p"6S4.69 L?jKቨُ& tj N9fq?ڬ)Oyv>',CzGJB9qSj4'8%M#q PJ;[ Q>LN]9VJR3g/48Ύ+N& b9FRىi#(OxNM큔;ki̿ktd݉3%ZgD< N9N`Ω 6Op2[tN7gn>>XSX{<%PWByH3L<5XP0R8LӔXA9w-5%fiNٗ;o/ %$ypG^盀' ݝ%8Rk)eo1hRN9qXmS$o$(͋|eQtw~Y{9wnٶ}bTg"#ٹj46DÅj“&7*sх.d4w3-'IQE.&'"&ZΎB@ᨋLT$Q'Hjp@}U N֭fyb\gg#hÕ0IZhrQB /"N6˔s9FMD'ypLiE.)m N6wSnm,7mJ0Dy^LWAPRIv$xWh,9,:Gu+8Nti3e{RhdOOm"(R" Z5q"xҹw9k"yGbyhaVّJC&NMrr* O͍V4sBrhD&aJ_sϞf|;UvPo.GJj,zެ'ySsM- *^ RVVFsSQxJQ*SJ(*%O3u,|!!*9ɒҞGo}˨ t<-^P LgffB<%ћm9 νzM$i!D^oT5>-w YG$9hI5nPDT'ʓsT&R;)x'\9ok!Ѣ"xR)C*=͜)X۩<ǿW&R`l?Sxt8)nt`~&"<4OYSr"wsk"r[zL9r SeiIJ4Om;n?/bKt& i} 5B/9MH&TLDDunAyR&8GC~zV7tHx~cv2j5{ʸ]8gx*'J[YTxQgKcv9N7x& Pie@<=eurOHŕq3wRmݵ>L%N4髼II[@_r#v/^O  |Kf _mT)K4sϭINDV'|b|h^t \~Ґ`8æq:=4t3M$9D8.;>5yT[8vtݏ7(@*< TP+O|;4Opn'gF镟/~w`njs0=,/15:9'IHf}|O(:?䏳tzx&ZzBSJHi~T/ Ƨ;$f/Q-7KڧVq"&N^Yjwݻ9ե4>fVd<i|B/@PWWy.I|#y(ojh<-@,H]DV+ !prOv0'{d '<5jws0>^gwR#|0Mi-q ̹kOh'ZJ%\t㹫7&Tc#ޓ8E}JNy,s(OHm|? !O Qx-HwP&qhwOe|kKmP@űs)vge%cD|4>ky|>t~yTYT4%i|<sOsIN#D"Dy܂~2qCh tf Nx<g,5?4j}%}(8y&O= D'l'GD)6]>>_mu;>aK~;bĻP-l&4-)+>|jXJ {z;O3'@tO"W+rx?44>!}ʆ7{4<;:trr.2;dzc)=M J%OɉFQ&MD|ݽ.|{JPVyW'"=0б9,\< ;S< OgLL'y N!R$"~GQaSṼc“Hi 1:D{y8'4ɓ@eh hĹuX}]=-8 tI94% Mx>>x)kFLYg)=muTo8TGE<0?94RiS>/DqNZܔ0ɓR,qzr8v'P h bˉ>Gw8ϳ!PH=2Z6!jyp<q7oy7j%LL2bO|tPO'[PGÜy&|XgGhPy)%عVOքS(S]rc$Pۆ%J'D~Rz /<)N#ݝ)%q³n7} FI^%$y7<<8{8'B3r?dmq:[ ˾X (vRD5[oTmEI&x^*^n2)~_5Ϻ,S& RZS#8Q .rwS N+ӴOo'bI=r~㬜e48 PzO(4 ΰG_)_eYsvHOJֿy&{_MvH J)R6N,eiܕT< #bZ=rQIENDB`admin/builder/assets/img/footer-social.png000064400000015574150515074560014640 0ustar00PNG  IHDR^ PLTE!!kﭶ½ſ﮸זּ﮻谴嬳ƿ鸷ߪ٪쿻ÿ侼z챹⶷ήȥҤ篹Ŝ赿ۺ߱سϷ3^<Ƕپ@Bͻ%vXXxx=T\ݶ­ߠׁٻ?Apc..kS(py蓸#K5jl?@zّڱ)dKqҼH!7IDATxkA𱩂܃RUX۪`-~U3XL#x 9XP()Pٙ;ni$3;DvXg׮]lكlwruN68ir4421B>R"#>62"Ԩk!5"k #;e|FB "F` ""J #; %jcMC"A`?"`ŨQJ% [5 yQ5HwTc"DDQ56h.ܢ>Dbyrul ְYH&Bh\z; !.qND@(ڨ՗%<RqyqDa+ODFu'TCaj[[#r&xռv^zdMJ"aa5b@zBCc8>xȭ"ʳyۖ-Z=آ.CJ{zyb QND6.uUmt|0D *vUbaxs-kF#j"#bRy|*ӰǠ*wp_S#rR[Ĥ򥈧$M+1웨cǨ#^~"ZF/ Ou! Q!"FLlDDP(_$Y{ҨRIa0 "^{rINiQ"qQJCDЄ9!"^ģdPeM~%W "C(‰݊`"R[!PBR2R".A%aP/Diԃj&)=vV@<I;*%DahBOUEP!DPת D{uNoo4"oT"!") dDҫ$ UfI]9u'U bd!{ݸ 2B& -A"#b hj-[HTCVGWYXBD:=(wPIđ z/!3x1ϕ2̓i_~MH,IeR O:LD?\꽠/s̐x\0::yU[11| 9g bHZv`,1hYF.^?"&76&0Ga ޾]0Ɩ#LqW"ifY0$ŐҶd~WD0a-$.J ?,dT&PdWF%̱Z,Lz BDni>o3C%[SBȖ!̎ulĈZ sÖB1:#iBݡU#u^rJYrp#0 z}z4|VJ/_6W(f*fPpWF\>}4M+wS(r޼CûH$*<=n$9xTQ=\Kh+Fà c;xoĹ#(>-^TD-%B̔[~910}xty31aB(\~NinZ똘fd9q_)vHGTGуwBK!1.,*+UNajӡ¤R$D{8a攦P]0GD>ZA<@\1&o-"嶶rkˣ& W޽D:#-DPU6Ia{#iz [o]k+ۣciX{N;;lA;I tZϛ!u[)r9ZĆW@MMi!:\ZhS*6l4F[[nնuOz޽;'>?{BB [OM/拜4D7lj¨&Mm4gΜq|1JBXu1m21ͩ ?6NZ cW.E8G {}7:($u8vޗmiQoC!t(Çxj+>Z:"@k"?IhSAE-Q/Jz+"$*E<,@qy-uQd1f#lk/kuKDLoX(…|*mY!E5q,Ը@d6 q*TDoޡGް7o;\oʉ ꅴD.m1>Ԭ4N!ZwXHZo/sb"!N@}c!-1me:|r:]DhvYѼCI BKFyh[7w/'(DMo1p8Fo_ [)W/ҩVWK 7Hd&SDe'aBx/DSf )aJمe:ֶ$hP-eZ'M)Pe@8zAT^$}`wV)D6&p*\Z ^>k3 !?x7\ aB#LqtT ;[1LDX( .:$TG4PNBph;^^(|"ů|O+jP;W訄]~=p❈);KDTj>t3eXQhzvB/P_Rz =H1 jix>eFftilE5!z™Ji:@ SOI -yM &O1CQŌvaC7M& s1"kV+dѾo*KԿh#l@"eԮ_OZP!eddx8ϯԴbªC5DT#0GiB/#?&rH!Jy:a@Yv?~;8W\~r -X?^߽Ia֓H`Ѐ—/_5O\a-[)iK{:ֻrr31y&ThD'{wǥ}{m_oku{]w/''f >\|~(C*Q@ E]&|.Ǜ;<yv<TaH.dՠ~ѣfd=7$essuvCB&fV&,5ۍX{ "pqqr5??A.9}' Q*G |0l@y=70p>)➞>x&}xUHT|[Cԁ犺e0t7P0ϋ @<}KCE" g3[PiL!yF3/Oq~h@t#&G2 >Q]UfB H_l(p>oHH" t #DQ Qh@˴BcCD#T!"xBj*#O\!!4HL [!hB%_t|!|V%<&Lh@qb/Se8_ >NyB#Vk֨O'*Bu[*Oq>y:gBiP*/ \%J`))R44wq||!0!b .P P'k4h@ф#D]PyЀo cTCLIL/Ğ>"Hð>0Da2M`;|GcN2]yEXF\[ Dy}^r<+ 9CTW(|#e@GК)0LOaVW;g6j2 B'h} z"^*D>נoMBuF#gEC+MF[p@)T"J ++%"!DB%‡rgX p+Cd**x.е FEH`*%67S 7R y X +Ԙ#DKy'jTʄ(OǑuNIo>)M)gF mrWL<-ߟB`LB$Є$wŕ5d~Y@gzC9wo]£7`_H`(L{{Mi8qUBIENDB`admin/builder/assets/img/welcome-2.png000064400000003601150515074560013650 0ustar00PNG  IHDRyշPLTE17Q8lqNSi{䘛#)Eݦ^bv]bv@F]硤ïei|X]q?D\tRNS_`oO?0@ϯ=IDATh _0GҋMCqxhO@B W27oJʎ:*7{{wׄԞl:~xY/K.޾t-V+mZ²peZX"[XtEjtYjDԲqnyEF>Q˻ԼG"9Q(FQLߛwbdXOaUBX"+ՇGV͏1>°:؂TV[`VVkVX|؂5 +M@rl"Fá]uh~g$AP^j]\5$gXix&4qtNzYN)2>R&B(OucFl5l@d9|np?1Y5":q0iX&ϥ++mK\K3lN:>Ɓ  G2ԏqagEYϷpLFjpMTm5&YOiL@|bıdME._pIGuǩGǔ 1 ~ƪJN&fGӺDT@t Knu!h97ԉ һpMixI ̓MdU8\: B*a]CsH}G^( @ ǭ/.'$B3Qi~3^@p*$ 85, 7 MX&NS+Yj#c$ϷPI n@^}Ku)7mٷa'aĽk#Y:W߃0vH3Qӷe*yߖmj-ێ; elD)[qzR%Ow@v}lOoya߯YmXՐUªV{zً[!\d}yU WTKs?{BP5\(KJ`os-.Td 2e9_IENDB`admin/builder/assets/img/featuredpost.png000064400000004602150515074560014565 0ustar00PNG  IHDRP qPLTEC݆p6rԤ~|LMhʴ©gPw\dZxAêsrh}E. IDATxA 0 D@ÄwFzH6pW$3)۟-lrN_GR_ɬF-)5ԕ{˗e uE| q̕{M((k+ڊ تv 41A(ͯib]aTHXp"#b@IM2C%@| %Rѓ$8`Qq;vINroA4^#qFSYb ѝjuDUSBTU"0iWGK%\Y•;\|3z)>/֖{yZB)>Spn=m$F|,,qCf\/ &p٪V\eOa`1/;>Zx>' ^U2rw&~ZDva}Z+S)Üqc] *V<N>[e}&gm}p.||LWRq{?*g'  [ !A[KeC٧|}kYq ryJ׈|,ql,Გ2h7CsjMG-zXY|ԃjR{m оـ(Ç}|oY<-CP>V|v?OT)ZoT'v߭k(%l_P!hP=N'WO#z* :.O=~h >^:G &٩=[OϬ4 Ajf9K* nRA(J2( {".yݙ{` _0dG53E}ig#<]h,wc~P`dγtҧ?_yi@ۿ!}$ļ@|J*G"ޖOI1/$繍t>?cf^xO/񘉁!0s>9h~$3yW3AgOGGS1Α\dK<D}VuLA!kQ4N`^^ P$]"_oT"gpcdzC}H;'z3ib4ɏ?y=L?9kgk}+Xq)>R`1Nlj¢>/yۃ^zD͛,-$^݉?BhC?^c{ 1_)HATuRvnAס :2JrP,ǂ8XR KN(˄)>vBYLi(&l&e(HC50k KAaY9.r}qw|Țڻ)xR{%pijx8Tׯ(XZB"":FyˆpFEHDO`eT{|n{GP7}s^SgD]P!p)#%Oů~rToJc4IIJUy9[;ZQQQQQQQQQQQQh6M.IENDB`admin/builder/assets/img/process-featured-post.png000064400000002100150515074560016305 0ustar00PNG  IHDRKKPLTE  %Zw(_}-m5}C۵aZurNJOOԲtRNS A)w 1&+$ocV20w2B/IDATXV0-ykוBLBBhZ(k5J&D?$; $oz]m $0`,YVR~yIQ'gQ:%Ggq$,GivHRBʋ* ǖDTEcYJ eHRM,;c8*kT?EX8-t xD(t*0,"ʲBѽ7fZ.uYQF"Ra`Ɉ(b5!_DqYFTJUA_zd$_Q9ŚJ,/{qU+Ba\CU_rgdcXso7csyWy9VO6[Ysj=X=w3{bGQ%OoW#h\~Y_>ks1]=:t~(=s(nĺ;$} admin/builder/assets/img/ext-socialwall.png000064400000013306150515074560015011 0ustar00PNG  IHDR{3PLTE $$$   ꩩܟޡ?=>騨? ߢㅅ몪㼼=؞ɽkkk炂ﭭC׆!!kꑑ臇鉉nڿ\R웛o?뗗?)j..zT)L~"'S05W`JCB`vݑD뛲ꔔ錌LJ<<0l7ցAc6"邕^ff8h2"s휩惤j\/j};mqa䅭CttrsxiYY*OtRNS !!a B"$ %B劊a剮rdљ:|{lTR;&18IDATxiAڵv%})EJɋ9;徒)C3 D\zgNc}2~;{yq8p8p8p8p8p8({{j>ʮ@6bWV-b+^ [*Ѽh+)$5J)e(1M_73}V"ǹ2POuZX +\K>Jks9f/j/sea; +ChBa'F(1_Rl*LNo%a*g1DHkle= s!n5M;ef; pbLƌ1)[Ā Y*FlcXHU[ҷ؛v3dG)F.ٰdHlȯP b<jHl-vƌlJ2T&b A2`aib 8@2'S8(o^j1dp1#=(jgw\j h"z hԟz >R_\~ ښ zK@ PqAe oYny악;ªkԕ|#@_$&RŌADc$BmbhkČjABMv?+"!Q05b<\|%X1)NE*ea2TC1xI_5A=\C1V!{3@=\"CD H31PKU @wĨi3E$oEvOSx1ClzNbx0)Hb -Ɗ$[K1`S%UmɇKpẍ́g\:HD2'-)aj1NMՂTAvzL1 SR[b(yFmH릈yڔC^DwĀT'. 3@Љy |@>br6U0e<H1l H1_CB.3 0'}5qbxb0>|k5!}w"bfj[v(1NyuHmH\OSΦ ,XV; |n[AM|A`:{=Rmtד>}+72%aש裬>?vJ\Z(4V%Ka FJڢ;%K `1LBWR@l/_ߜDQiM iRMЧA-@jx[؏h)ۊĹH+iAr3|<> zFqh4)BTǠA{ d1Z[3f J 4oH`B3R9pSb(R>(6Vb, ㉢_,KY~7{}3a 0Ι9}X_ʪ9(m&?c9m'e|73L3_+JQQYf S~|y_t0"֣{Ɛ#=Q-Di"nf:1vǚw1Je݌3u(1cSBϰiǐƇd8bAIߐ5Lށ2Ghq+ G1dx1qU|\gb$ӫ?FVZWCrUU+\ -F8 \ia:B(k33]<(dϾDQ"nƒPH5BR$D%kDY=-k'sk¸3nj|s=qϹ˜S`QahnxEf*yl*;€T!XS>F?*2My-Qm^#u23:9-.CЋ'(puɘ)sg )+d$wNe2?A3>#I\dfb]hMψë7s2?_ɞtd̕8^ m6Ϙ/CDkS={6 z3Cq[NT.CFM[m۶~͛3$02B2V[j тu! JHQD%䀆 ,``ȁ5M0 B/d1FM&ۊւaԠGos} |'"FE6lrR[4ͬޔX$m㺁VTC d0.)$+-3jP'(G$* RTBlʣ…;,+ ` OFxF=S1օr6OYhmVG%%5{.lf yF`Tg~E\;/=c`3B43գH25J2U]].iem6MhUn#||EՒʯV3ӡ-Ϟ!+%C|=R>Ba : 3(gksi䂰2XJC?MM-K%Z%glUͥNMt9sb4UZSL1$Z=]Qӧ m Wf~FkCK1:,97/ܒ=#0/R;vdtsr&d`=?PW3$h#C$?횙 xhЖ%BGeNecrȒG-Nєs9$ xgx|W,>]yU8BaMP>O3ɯ<{*-ϡmmƁׁ3LU"rHQ ;}~֦=dTySϡmڊQT%tw&Ŝצ1!Il,͔ma%;l-g8zC5j n"(QAD!j(k'UBoԒfc΁[ h\=8*- ͵b@gAu1^E 0EMlzFoaQx{iKP=VJ@% M%T!4\(! % ŭkgAMm%tZM)WK5A@tjR3+Pz9Dqxu KGH0> a$a} dPA1J$`Tsw֙[ | R *@- :Z@+ X`fX`BK@ |.HWz#UMV Xh.NQS%`B `Dk$h=h GؤItPes)IrdF;g3ի٫e1|y ε,o]d4/Bw7*Ǻg8[(d@g&5*osgO֐*?!GLq \{mך:홷x3R,/Ƕ=m|"`Lx7$(2Z,\,o7q4 \1Ax(wQ_aSa}oƑy!Ú).qQ7(2.޳IdhWdCX 勝;n)AŤx|R\ttT:  'C>=~ıc;w=hl_ׁ^yEZЍ̔U?s>zԔg ^v 3ܹN%^IC衙3:J Aët>zF 9?IENDB`admin/builder/assets/img/singlealbum.png000064400000002255150515074560014364 0ustar00PNG  IHDRP qGPLTEkCۆqɚѽڥ```처Kױﴚd{rx鮕hg橎d@@@ꂽ˩ʯ빤궟{ooo쇿[ޭМǿաϝo???O_!IDATxYw@q$QJD+QjMm/;/m}_séB{0 0 0 0 0 0vzoN8M bA=CvĮjt1IVA=zsGs ypp$}Zt-gI ]s0bWPv~]ete׉ݟnϒ ~4ک7+PȃMd{)r=/oxIxc7|sQr2O3MvܷvSzk;\Ir]P3P؀7ξjq@IiS5U:Y0I5>njOpFG֘_Y~)@ˌpy,"$$0[n-ȉ XK,y,ZJgG<ȢjT#K h1ARF)JNH {(G$HKq6 aaaaaOyosZ*IENDB`admin/builder/assets/css/builder.css000064400000402055150515074570013533 0ustar00body{ background: #red; --cl-orange: #FE544F; --cl-dark:#2C324C; --error-red: #D72C2C; --customizer-blue: #0096CC; --dark-blue: #2A65DB; } .sb-tr-1{-webkit-transition: all .1s ease-in-out; transition: all .1s ease-in-out;} .sb-tr-2{-webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out;} .sb-tr-3{-webkit-transition: all .3s ease-in-out; transition: all .3s ease-in-out;} .sb-tr-4{-webkit-transition: all .4s ease-in-out; transition: all .4s ease-in-out;} .sb-tr-5{-webkit-transition: all .5s ease-in-out; transition: all .5s ease-in-out;} .sb-tr-6{-webkit-transition: all .6s ease-in-out; transition: all .6s ease-in-out;} .sb-tr-7{-webkit-transition: all .7s ease-in-out; transition: all .7s ease-in-out;} .sb-tr-8{-webkit-transition: all .8s ease-in-out; transition: all .8s ease-in-out;} .sb-tr-9{-webkit-transition: all .9s ease-in-out; transition: all .9s ease-in-out;} .sb-tr-10{-webkit-transition: all 1s ease-in-out; transition: all 1s ease-in-out;} .sbi-bg-1{ background: #2A65DB; } /**** Buttons */ .sb-button { display: flex; flex-direction: row; justify-content: center; align-items: center; border-radius: 2px; cursor: pointer; outline: none; box-shadow: none; border: none; -webkit-transition: all .15s ease-in-out; transition: all .15s ease-in-out; } .sb-button-standard{ position: relative; font-style: normal; font-weight: 600; font-size: 14px; padding: 10px 20px 10px 39px; line-height: 16px; border: unset; cursor: pointer; } .sb-button-standard svg { width: 16px; height: 16px; position: absolute; left: 13px; right: auto; top: 10px; bottom: auto; } .sb-button-small.sb-button-left-icon { padding-left: 32px; } .sb-button-small.sb-button-right-icon { padding-right: 32px; } .sb-button-small.sb-button-left-icon svg { position: absolute; left: 13px; } .sb-button-small.sb-button-right-icon svg { position: absolute; right: 13px; } .sb-button-standard.sb-button-right-icon { padding: 10px 39px 10px 20px; } .sb-button-standard.sb-button-right-icon svg { right: 13px; left: auto; } .sb-button-small { position: relative; font-style: normal; font-weight: 600; font-size: 12px; padding: 6px 12px; line-height: 160%; } .sb-button-no-border { border-radius: 0 !important; border: none !important; } /*orange*/ .sbi-btn-orange{ background: #FE544F!important; color: #fff!important; } .sbi-btn-orange:hover{ background: #EC352F!important; color: #fff!important; } .sbi-btn-orange:focus{ background: #BC120E!important; color: #fff!important; } /*red*/ .sbi-btn-red{ background: #D72C2C!important; color: #fff!important; } .sbi-btn-red:hover{ background: #DF5757!important; color: #fff!important; } .sbi-btn-red:focus{ background: #841919!important; color: #fff!important; } /*red*/ .sbi-btn-blue{ background: #0068A0!important; color: #fff!important; } .sbi-btn-blue:hover{ background: #0096CC!important; color: #fff!important; } .sbi-btn-blue:focus{ background: #004D77!important; color: #fff!important; } /*grey*/ .sbi-btn-grey{ background: #F3F4F5!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sbi-btn-grey:hover{ background: #fff!important; color: #141B38!important; border: 1px solid #DCDDE1!important; } .sbi-btn-grey:focus{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } /*dark*/ .sbi-btn-dark{ background: #2C324C!important; color: #fff!important; } .sbi-btn-dark:hover{ background: #434960!important; color: #fff!important; } .sbi-btn-dark:focus{ background: #141B38!important; color: #fff!important; } .sb-dark-hover:hover svg, .sb-dark-hover:hover path{ fill: #141B38; } /*disabled*/ .sbi-btn-orange[data-active="false"], .sbi-btn-blue[data-active="false"], .sbi-btn-red[data-active="false"], .sbi-btn-grey[data-active="false"], .sbi-btn-dark[data-active="false"]{ background: #E8E8EB !important; color: #8C8F9A !important; } /* Text */ #sb_instagram{ overflow-x: hidden; } #sbi-builder-app h1:not(#sb_instagram h1) { font-style: normal; font-weight: 600; font-size: 36px; line-height: 125%; color: #141B38; margin: 0; letter-spacing: 0; } #sbi-builder-app h2:not(#sb_instagram h2) { font-style: normal; font-weight: 600; font-size: 32px; line-height: 125%; margin: 0; letter-spacing: 0; } #sbi-builder-app h3:not(#sb_instagram h3):not(.sb_instagram_header h3) { font-style: normal; font-weight: 600; font-size: 24px; line-height: 120%; margin: 0 0 4px 0; letter-spacing: 0; } #sbi-builder-app h4:not(#sb_instagram h5) { font-style: normal; font-weight: 600; font-size: 18px; line-height: 140%; margin: 0 0 4px 0; letter-spacing: 0; } .sbi-fb-feedtypes-pp-ctn h4 { font-size: 24px !important; margin-bottom: 28px !important; } #sbi-builder-app .sb-small-p, #sbi-builder-app .sb-standard-p{ font-style: normal; font-weight: normal; font-size: 14px; line-height: 160%; color: #8C8F9A; margin: 0; } #sbi-builder-app .sb-standard-p{ font-size: 16px; color: #141B38; } #sbi-builder-app .sbi-fb-source-inp::placeholder { color: #8C8F9A; font-size: 14px; font-weight: normal; } #sbi-builder-app .sb-bold { font-weight: 600; } #sbi-builder-app .sb-dark-text { color: #141B38; } #sbi-builder-app .sbi-btn-orange .sb-small-p, #sbi-builder-app .sbi-btn-blue .sb-small-p, #sbi-builder-app .sbi-btn-red .sb-small-p, #sbi-builder-app .sbi-btn-dark .sb-small-p{ color: #fff; } #sbi-builder-app .sb-caption { font-style: normal; font-weight: normal; font-size: 13px; line-height: 150%; color: #141B38; } #sbi-builder-app .sb-caption.sb-caption-lighter { color: #5F6368; } #sbi-builder-app .sb-small { font-style: normal; font-weight: bold; font-size: 10px; line-height: 160%; letter-spacing: 0.02em; text-transform: uppercase; color: #141B38; } #sbi-builder-app .sb-lighter { color: #434960; } #sbi-builder-app .sb-lightest { color: #74777D; } #sbi-builder-app .sb-small-text { font-size: 12px; } /* Positioning */ .sb-icon-label { display: flex; flex-direction: row; justify-content: flex-start; align-items: center; } /* Misc Stylings */ .sb-flex-center { display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-align: center; -webkit-align-items: center; -webkit-box-align: center; align-items: center; } .sb-box-shadow { box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); } #sbi-builder-app .sb-icon-small svg { height: 10px; } /* Social Links */ .sbi-cl-facebook, .sbi-clhv-facebook:hover{ color: #006BFA!important; } .sbi-bg-facebook, .sbi-bghv-facebook:hover{ background: #006BFA!important; } .sbi-cl-instagram, .sbi-clhv-instagram:hover{ color: #BA03A7!important; } .sbi-bg-instagram, .sbi-bghv-instagram:hover{ background: #BA03A7!important; } .sbi-cl-twitter, .sbi-clhv-twitter:hover{ color: #1B90EF!important; } .sbi-bg-twitter, .sbi-bghv-twitter:hover{ background: #1B90EF!important; } .sbi-cl-youtube, .sbi-clhv-youtube:hover{ color: #EB2121!important; } .sbi-bg-youtube, .sbi-bghv-youtube:hover{ background: #EB2121!important; } .sbi-cl-linkedin, .sbi-clhv-linkedin:hover{ color: #007bb6!important; } .sbi-bg-linkedin, .sbi-bghv-linkedin:hover{ background: #007bb6!important; } .sbi-cl-mail, .sbi-clhv-mail:hover{ color: #666!important; } .sbi-bg-mail, .sbi-bghv-mail:hover{ background: #666!important; } #sbi-builder-app{ font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;; visibility: hidden; opacity: 0; } #sbi-builder-app[data-app-loaded="true"]{ visibility: visible; opacity: 1; } .sbi-builder-app a, .sbi-builder-app a:focus{ text-decoration: none; /*color: inherit;*/ outline: none; } .sbi-fb-btn{ display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 9px 38px; font-style: normal; font-weight: 500; font-size: 14px; line-height: 17px; border-radius: 2px; cursor: pointer; color: #fff; outline: none; box-shadow: none; border: none;; } .sbi-fb-btn:focus{ box-shadow: none; } .sbi-fb-fs, .sb-fs{ width: 100%; position: relative; float: left; box-sizing: border-box; } .sbi-fs-a{ width: 100%; height: 100%; display: block; position: absolute; left: 0; top: 0; z-index: 1; } .sb-btn:focus{ outline: none; } #wpcontent, .instagram-feed_page_sbi-feed-builder #wpcontent{ padding-left: 0px!important; } #wpfooter{ display: none; } #wpbody-content{ padding-bottom: 0px; } #wpbody{ padding-left: 0px!important; } .sbi-fb-wrapper{ max-width: 92%; position: relative; margin: auto; color: #141B38; } .sbi-fb-fs-boss{ position: fixed; height: 100vh; width: 100%; left: 0; top: 0; bottom: 0; right: 0; background: rgba(0,0,0,.4); z-index: 9989; } /* Header */ .sbi-fb-create-ctn{ margin-top: 104px; padding: 0 54px; box-sizing: border-box; width: 100%; } .sbi-fb-header{ height: 64px; position: absolute; display: flex; flex-direction: row; justify-content: space-between; align-items: center; background: #fff; padding: 0px 52px; z-index: 99; } .sbi-fb-header-left { display: flex; } .sbi-fb-header-left .sb-social-wall-link-wrap { margin-left: 30px; } .sbi-fb-hd-logo { display: flex; vertical-align: middle; align-items: center; gap: 5px; } .sbi-fb-hd-logo .sb-logo-letters-wrap { transform: translate(0px, -2px); } .sbi-fb-hd-logo .breadcrumb-title { font-size: 14px; font-weight: 400; line-height: 22px; letter-spacing: 0em; margin-left: 4px; } .sbi-csz-header.sbi-fb-header{ position: fixed!important; padding: 0 20px; } .sbi-csz-header-insider{ width: calc(100% - 160px); display: flex; flex-direction: row; justify-content: space-between; align-items: center; height: 52px; } body.jetpack-masterbar .sbi-csz-header-insider { width: calc(100% - 272px); } @media all and (max-width: 960px) { .sbi-csz-header-insider{ width: calc(100% - 36px); } .sb-customizer-ctn .sb-customizer-sidebar{ left: 36px; } body.jetpack-masterbar .sb-customizer-sidebar { left: 36px; } body.jetpack-masterbar .sbi-csz-header-insider { width: calc(100% - 36px); } } .sbi-fb-hd-btn{ cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; position: relative; border: 1px solid; -webkit-transition: all .15s ease-in-out; transition: all .15s ease-in-out; } .sbi-fb-hd-btn i{ margin: 0px 5px; } .sbi-fb-full-wrapper { padding: 0 53px; padding-top: 82px; } .sbi-csz-hd-actions{ display: flex; justify-content: center; align-items: center; } .sbi-csz-hd-actions > button{ margin-left: 10px; } .sbi-csz-btn-embd{ color: #fff; background: var(--cl-dark); border-color: var(--cl-dark); } .sbi-csz-btn-save{ color: #fff; background: var(--cl-orange); border-color: var(--cl-orange); } .sbi-csz-hd-name{ display: flex; justify-content: center; align-items: center; height: 45px; } .sbi-csz-hd-name strong{ font-size: 18px; } .sbi-csz-hd-name[data-edit="true"] strong{ display: none; } .sbi-csz-hd-name input[type="text"]{ border-radius: 0px; border: 0px; background: #CCE7FF; outline: none; font-size: 18px; font-weight: 700; display: none; } .sbi-csz-hd-name[data-edit="true"] input[type="text"]{ display: block; } .sbi-csz-hd-name input[type="text"]:focus{ outline: none!important; border: 0px!important; box-shadow: none!important; } .sbi-csz-name-ed-btn{ width: 22px; height: 22px; cursor: pointer; margin: 0 10px; background: #E8E8EB; border: 1px solid #E8E8EB; outline: none; } .sbi-csz-name-ed-btn:focus, .sbi-csz-name-ed-btn:hover{ outline: none; background-color: #fff; } .sbi-csz-name-ed-btn svg{ width: 11px; fill: #141B38; float: left; margin-left: -1px; } /* Welcome Screen Empty State */ .sbi-fb-wlcm-header{ display: flex; align-items: center; margin-bottom: 28px; margin-top: 23px; } #sbi-fb-full-wrapper .sbi-fb-wlcm-header { margin-bottom: 34px; } .sbi-fb-wlcm-header h3, .sbi-fb-create-ctn h3{ font-weight: 600; font-size: 32px; line-height: 40px; padding: 0; margin: 0; float: left; } .sbi-fb-btn-new{ background: var(--cl-orange); position: relative; float: left; margin-left: 20px; font-size: 12px; padding: 8px 12px 8px 32px; font-weight: 700; } .sbi-fb-btn-new svg{ width: 10px; height: 10px; position: absolute; left: 12px; } .sbi-fb-inf-cnt{ position: relative; background: #fff; padding: 27px; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; max-width: 100%; } .sbi-fb-inf-num{ width: 30px; height: 30px; position: relative; float: left; display: flex; justify-content: center; align-items: center; font-size: 12px; font-weight: 600; color: #141B38; margin-right: 20px; } .sbi-fb-inf-num span{ z-index: 1; } .sbi-fb-inf-num:before{ content: ''; position: absolute; width: 100%; height: 100%; background: #D8DADD; border-radius: 50%; } .sbi-fb-inf-txt{ float: left; } /*.sbi-fb-inf-txt strong{ display: block; font-size: 20px; line-height: 1em; font-weight: bold; margin-bottom: 8px; }*/ .sbi-fb-inf-txt span{ display: block; font-size: 16px; color: #5F6368; line-height: 1.5em; } .sbi-fb-wlcm-inf-1 { padding-left: 297px; } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-svg{ position: absolute; left: 191px; top: 32px; /*float: left; margin-top: 30px; margin-left: 230px; position: relative; margin-right: 25px;*/ } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-svg svg{ margin-top: -45px; } .sb-head { position: absolute; top: -2px; left:-4px; } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-cnt{ float: left; width: 523px; margin-bottom: 24px; } .sbi-fb-wlcm-inf-2{ display: flex; justify-content: space-between; padding-left: 152px; } .sbi-fb-wlcm-inf-2 .sbi-fb-inf-cnt{ float: left; width: 590px; margin-bottom: 29px; height: 67px; display: flex; align-items: center; } .sbi-fb-wlcm-inf-2 .sbi-fb-inf-img{ position: absolute; right: 15px; top: -15px; } .sbi-fb-wlcm-inf-3{ display: flex; justify-content: flex-start; align-items: center; padding-left: 297px; } .sbi-fb-wlcm-inf-3 .sbi-fb-inf-cnt{ float: left; width: 620px; height: 80px; display: flex; justify-content: center; align-items: center; } .sbi-fb-wlcm-inf-3 .sbi-fb-inf-img{ float: left; left: 10px; top: -10px; position: absolute; } .sbi-fb-wlcm-inf-2 .sbi-fb-inf-num, .sbi-fb-wlcm-inf-3 .sbi-fb-inf-num{ margin-top: -20px; } .sbi-fb-types-ctn, .sbi-fb-slctsrc-ctn, .sbi-fb-section-wh{ background: #fff; border: 1px solid #E7E7E9; } .sbi-fb-wrapper h3, .sbi-fb-section-wh h3{ font-size: 32px; line-height: 39px; font-weight: 600; } .sbi-fb-create-ctn h3{ margin-bottom: 30px; } .sbi-fb-types h4, .sbi-fb-section-wh h4 { font-size:20px; line-height: 24px; font-weight: 600; } #sbi-builder-app .sbi-fb-create-ctn h4, #sbi-builder-app .sbi-fb-feedtypes-pp-ctn h4{ margin-bottom: 1px; } #sbi-builder-app .sbi-fb-feedtypes-pp-ctn .sbi-fb-types { margin-top: 20px; } #sbi-builder-app .sbi-fb-adv-types .sbi-adv-types-heading{ font-style: normal; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; color: #8C8F9A; } .sbi-fb-types-desc{ font-size: 14px; color: #434960; margin-bottom: 33px; display: block; } .sbi-fb-types, .sbi-fb-adv-types{ padding: 22px 35px 0; } .sbi-fb-adv-types { padding-top: 0; } #sbi-builder-app .sbi-fb-type-el-info a, .sbi-business-required{ color: #0068A0; font-size: 12px; display: flex; align-self: center; } #sbi-builder-app .sbi-fb-type-el-info a span{ margin-right: 7px; } #sbi-builder-app .sbi-fb-type-el-info a svg, .sbi-business-required svg{ height: 16px; line-height: 12px; vertical-align: top; margin-top: 1px; } .sbi-fb-types-list{ display: grid; grid-template-columns: 24.25% 24.25% 24.25% 25.25%; grid-column-gap: 1%; margin-bottom: 31px; } /* .sbi-fb-adv-types .sbi-fb-types-list{ grid-template-columns: 24.25% 24.25% 24.25% 24.25%; } */ .sbi-fb-heading { margin-bottom: 24px; width: 100%; float: left; } .sbi-fb-heading h1{ float: left; } .sbi-fb-heading .sbi-fb-btn{ float: right!important; } .sbi-fb-adv-types .sbi-fb-types-list{ margin-bottom: 71px; } .sbi-fb-type-el{ display: flex; flex-direction: column; align-items: flex-start; padding: 0; position: relative; background: #fff; border: 1px solid #F1F1F1; border-radius: 3px; cursor: pointer; box-sizing: border-box; } .sbi-fb-type-el:not([data-type="socialwall"]):hover, .sbi-fb-adv-types .sbi-fb-type-el:not([data-type="socialwall"]):hover{ border: 1px solid #F6966B; } .sbi-fb-adv-types .sbi-fb-type-el{ border: 1px solid #FFDBBA; } .sb-control-feedtype-ctn .sbi-fb-type-el{ border: 2px solid #E8E8EB; margin-bottom: 7px; } .sb-control-feedtype-ctn .sbi-fb-type-el-info{ margin-top: 14px } .sbi-fb-type-el[data-active="true"], .sbi-fb-adv-types .sbi-fb-type-el[data-active="true"]{ border: 2px solid var(--cl-orange)!important; } .sbi-fb-type-el[data-active="true"]:not([data-type="socialwall"]):after{ content: ''; position: absolute; width: 10px; height: 4px; border-left: 2px solid #fff; border-bottom: 2px solid #fff; z-index: 3; right: 5px; top: 7px; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-fb-type-el:before{ content: ''; position: absolute; width: 24px; height: 24px; right: 0px; top: 0px; z-index: 2; background: #DCDDE1; } .sbi-fb-type-el[data-active="true"]:before{ background: var(--cl-orange) } .sbi-fb-type-el[data-type="socialwall"]:before{ display: none; } .sbi-fb-type-el-img{ display: flex; flex-direction: column; justify-content: center; align-items: center; background: #F1F1F1; border: 2px solid #F1F1F1; border-bottom: 1px solid #fff; } .sbi-fb-type-el[data-active="true"] .sbi-fb-type-el-img{ border: 1px solid #F1F1F1; border-bottom: 2px solid #fff; } .sbi-fb-type-el-img svg { max-width: 100%; } .sbi-fb-adv-types .sbi-fb-type-el-img{ background: #FCF4EF; } .sbi-fb-type-el-info{ display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; flex: 1 1 auto; padding: 0 13px 13px; } .sbi-fb-type-el-link{ font-size: 13px; font-weight: 400; margin-bottom: 5px; } .sb-control-feedtype-ctn .sbi-fb-type-el-info{ padding: 15px 70px 25px; } .sb-control-feedtype-ctn .sbi-fb-type-el-info strong{ font-size: 14px; } #sbi-builder-app .sbi-fb-type-el p { margin: 11px 0 4px; } #sbi-builder-app .sbi-fb-type-el[data-active="true"] p{ margin-top: 10px; } #sbi-builder-app .sbi-fb-type-el[data-active="true"] .sbi-fb-type-el-info { padding-bottom: 12px; } #sbi-builder-app .sbi-fb-type-el p svg { width: 14px; height: 14px; margin-left: 5px; vertical-align: middle; } /*.sbi-fb-type-el-info strong{ font-weight: 600; font-size: 16px; line-height: 19px; margin-bottom: 10px; text-transform: capitalize; display: flex; justify-content: center; align-items: center; } .sbi-fb-type-el-info strong i{ color: #ed8000; margin-left: 5px; font-size: 13px; margin-top: 2px; } .sbi-fb-type-el-info span{ font-size: 13px; line-height: 1.4em; color: #74777D; }*/ .sbi-fb-adv-types .sbi-fb-type-el-img { border-color: #FCF4EF; } .sbi-fb-ft-action { border-top: 1px solid #D8DADD; padding: 30px 40px; margin-top: 63px; } .sbi-fb-slctfd-action .sbi-fb-wrapper{ display: flex; align-items: center; justify-content: flex-end; } .sbi-fb-slctfd-action{ padding: 16px 0; } .sbi-fb-slctf-nxt{ height: auto; padding: 7px 36px 7px 37px; } .sbi-fb-slctf-back{ margin-right: auto; height: auto; padding: 7px 37px 7px 36px; } .sbi-fb-slctf-back svg, .sbi-fb-slctf-nxt svg { width: 6px; height: 10px; } .sbi-fb-slctf-back span { display: inline-block; margin-left: 15px; line-height: 160%; } .sbi-fb-slctf-nxt span { display: inline-block; margin-right: 15px; line-height: 160%; } .sbi-fb-btn-ac{ opacity: 0.6; } .sbi-fb-btn-ac[data-active="true"]{ opacity: 1; } .sb-control-single-id-ctn{ margin-top: 35px; padding: 25px 0px; } .sb-control-single-id-ctn:before, .sb-control-before-brd:before { content: ''; position: absolute; border-top: 1px solid #DCDDE1; height: 2px; top: 0px; left: -20px; width: calc(100% + 40px); } .sb-control-single-id-input{ display: flex; justify-content: center; align-items: center; margin-top: 7px; } .sb-control-single-id-input input{ height: 45px; float: left; background: #fff; margin-top: 6px; margin-right: 7px; } /* Video Type Chooser */ .sbi-fb-section-wh.sbi-fb-section-videos{ padding: 50px 21px 54px 30px; } .sbi-fb-videotype-chooser{ display: grid; grid-template-columns: 49% 49%; grid-column-gap: 1%; } .sbi-fb-section-videos{ flex-direction: column; } .sbi-fb-section-videos .sbi-fb-section-video-playlist{ margin-top: 30px; } .sbi-fb-section-video-playlist .sbi-fb-wh-inp{ margin-top: 10px; margin-bottom: 10px!important; } .sbi-fb-section-videos .sbi-fb-sglelm-left{ padding-right: 0px; } /* Source Screen */ .sbi-fb-sec-heading > span{ font-size:14px; color: #434960; line-height: 1.7em; display: block; } #sbi-builder-app .sbi-fb-sec-heading h4{ margin-bottom: 2px; } #sbi-builder-app .sbi-fb-slctsrc-ctn .sbi-fb-sec-heading h4{ margin-bottom: 2px !important; } .sbi-fb-sec-heading { margin-bottom: 14px; } .sbi-builder-app .sbi-fb-slctsrc-content,.sbi-fb-section-wh-insd{ padding: 23px 30px; } .sbi-fb-slctsrc-ctn h4,.sbi-fb-section-wh-insd h4{ font-size: 20px; padding: 0px; margin: 0px; } .sbi-fb-srcslist-ctn{ display: grid; grid-template-columns: 32.66% 32.66% 32.66%; grid-column-gap: 1%; margin-bottom: 28px; } .sbi-fb-srcs-item{ width: 100%; cursor: pointer; height: 62px; margin: 1% 0; border-radius: 3px; border: 1px solid #E7E7E9; display: flex; position: relative; } .sbi-fb-srcs-item[data-disabled="true"]{ background: #F3F4F5; } .sbi-fb-srcs-item[data-disabled="true"] .sbi-fb-srcs-item-inf{ opacity: .55; } #sbi-builder-app .sbi-fb-srcs-item .sbi-fb-srcs-item-inf .sbi-fb-srcs-item-name { color: #141B38; padding-right: 44px; } /*Disabled Controls*/ .sb-control-elem-ctn[data-disabled="true"] input[type="text"], .sb-control-elem-ctn[data-disabled="true"] input[type="number"], .sb-control-elem-ctn[data-disabled="true"] input[type="date"], .sb-control-elem-ctn[data-disabled="true"] textarea{ background: #f0f0f0!important; border-color: #D0D1D7!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-colorpicker-swatch{ background: #D0D1D7!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-checkbox{ background: #D0D1D7!important; border-color: #c1c1c1!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-toggle-elm{ background: #e5e6e7!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-toggle-elm{ border-color: #c1c1c1!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-toggle-elm[data-active="true"]{ border-top: 0px; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-toggle-elm .sb-control-toggle-deco{ border-color: #bbb!important; } .sb-control-elem-ctn[data-disabled="true"] .sb-control-toggle-elm[data-active="true"] .sb-control-toggle-deco{ border-color: #8C8F9A!important; } #sbi-builder-app .sbi-fb-srcs-item .sbi-fb-srcs-item-inf .sbi-fb-srcs-item-name span { max-height: 30px; display: block; overflow: hidden; line-height: 1.1; padding-bottom:1px; color: #141B38; } #sbi-builder-app .sbi-fb-srcs-item:hover{ border-color: #86D0F9; } #sbi-builder-app .sbi-fb-srcs-item[data-active="true"]{ border-color: #0096cc; } .sbi-fb-source-top .sbi-fb-srcs-item{ margin-bottom: 0px; } #sbi-builder-app .sbi-fb-srcs-new{ display: flex; justify-content: center; align-items: center; background: #EBF5FF; border: 1px solid #EBF5FF; } #sbi-builder-app .sbi-fb-srcs-new span{ margin-left: 13px; color: #0096CC; } .sbi-fb-srcs-new i{ font-size: 14px; padding: 0 10px; margin-left: -10px; } .sbi-fb-srcs-item-chkbx{ width: 40px; height: inherit; display: flex; justify-content: center; align-items: center; margin: 0 16px 0 7px; } .sbi-fb-srcs-item-chkbx-ic,.sbi-fb-chbx-round{ width: 16px; height: 16px; box-sizing: border-box; position: relative; border-radius: 50px; border: 2px solid #8c8f9a; } [data-source="active"] .sbi-fb-srcs-item-chkbx-ic{ border-radius: 2px; } [data-active="true"] .sbi-fb-srcs-item-chkbx-ic, [data-active="true"] > .sbi-fb-chbx-round, .sbi-fb-source-popup [data-active="true"] > .sbi-fb-chbx-round{ border-color: #0096cc; background: #0096cc; } [data-source="active"] [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before{ content: ''!important; position: absolute!important; width: 8px!important; height: 3px!important; border-left: 2px solid #fff; border-bottom: 2px solid #fff; top: 2px!important; right: 1px!important; left: unset!important; background: unset!important; border-radius: unset!important; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } [data-multifeed="inactive"] [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before, [data-active="true"] > .sbi-fb-chbx-round:before, .sbi-fb-source-popup .sbi-fb-source-list [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before, .sbi-fb-section-videos [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before{ content: ''; position: absolute; height: 6px; width: 6px; background: #fff; border-radius: 25px; left: 3px; top: 3px; } .sbi-fb-sources-empty-ctn{ padding: 24px 32px 28px 24px; background: #F9F9FA; border: 1px dashed #DCDDE1; margin-top: 10px; display: flex; align-items: center; } .sbi-fb-sources-empty-txt{ font-style: normal; font-weight: normal; font-size: 16px; line-height: 160%; color: #141B38; } .sbi-fb-sources-empty-btn-ctn{ margin-left: auto; } .sb-addsources-btn{ color: #fff; height: 27px; padding: 9px 23px; } .sb-addsources-btn svg{ margin-right: 10px; fill: currentColor; width: 14px; height: 14px; } .sbi-fb-mr-feeds,.sbi-fb-section-wh{ margin-top: 8px; background: #fff; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); display: flex; align-items: center; } .sbi-fb-mr-fd-img { float: left; margin-right: 6%; width: 28%; line-height: 0; } .sbi-fb-mr-fd-img img{ width: 100%; } .sbi-fb-mr-fd-heading{ font-weight:600; font-size: 18px; line-height: 1.7em; margin-bottom: 24px; float: left; } .sbi-fb-mr-fd-list{ margin-bottom: 10px; width: 100%; float: left; } .sbi-fb-mr-fd-item{ box-sizing: border-box; position: relative; float: left; border: 1px solid #DCDDE1; border-radius: 2px; margin-right: 8px; height: 38px; width: 160px; color: #141B38; font-size: 14px; font-weight:600; text-transform: capitalize; display: flex; justify-content: center; align-items: center; transition: all .15s ease-in-out; } .sbi-icon-platform-wrap { width: 100%; display: flex; justify-content: left; align-items: center; margin-left: 13px; } .sbi-fb-mr-fd-ic { margin-right: 9px; } .sbi-fb-mr-fd-ic svg{ height: 16px; fill: currentColor; float: left; } .sbi-fb-mr-fd-ch{ position: absolute; right:14px; } #sbi-builder-app .sbi-fb-mr-fd-heading h3 { margin-bottom: 21px; max-width: 385px; } /*Embed Popup*/ .sbi-fb-embed-step-1{ margin-top: 36px; } .sbi-fb-embed-step-1 > div{ padding: 0 20px; } .sbi-fb-embed-step-1-top{ padding-bottom: 53px!important; border-bottom: 1px solid #E8E8EB; margin-bottom: 42px; } #sbi-builder-app .sbi-fb-embed-step-1 h4{ margin-bottom: 12px; } .sbi-fb-embed-input-ctn{ display: flex; } .sbi-fb-embed-input-ctn input, .sbi-fb-embed-input-ctn input[type="text"]{ position: relative; font-style: normal; font-weight: normal; font-size: 16px; line-height: 160%; color: #141B38; height: 44px; width: 77%; box-sizing: border-box; border-radius: 0px; border: 1px solid #D0D1D7!important; border-right: 0px!important; } .sbi-fb-embed-input-ctn input:focus, .sbi-fb-embed-input-ctn .sbi-fb-hd-btn:focus{ box-shadow: none!important; outline: none!important } .sbi-fb-embed-input-ctn .sbi-fb-hd-btn{ width: 23%; border-bottom-left-radius: 0px; border-top-left-radius: 0px; } .sbi-fb-embed-input-ctn svg{ width: 17px; fill: currentColor; float: left; margin-right: 10px; } .sbi-fb-embed-step-1-bottom h4{ text-align: center; } .sbi-fb-embed-btns-ctn{ display: flex; justify-content: center; gap: 2%; margin-top: 14px; margin-bottom: 60px; } .sbi-fb-embed-btn{ cursor: pointer; width: 100%; max-width: 400px; height: 50px; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; display: flex; align-items: center; justify-content: space-between; box-sizing: border-box; padding: 0 20px; position: relative; color: #141B38; font-size: 16px; font-weight: 500; } .sbi-fb-embed-btn .sb-icon-label svg{ fill: currentColor; width: 18px; margin-right: 10px; float: left; } .sbi-fb-embed-popup .sb-embed-breadcrumb { display: flex; align-items: center; padding: 25px 30px 0; margin-bottom: 2px; } .sb-embed-breadcrumb a { font-style: normal; font-weight: bold; font-size: 10px; line-height: 160%; letter-spacing: 0.08em; text-transform: uppercase; color: #434960; cursor: pointer; } .sb-embed-breadcrumb a:hover { color: #141B38; } .sb-embed-breadcrumb svg { margin-right: 8px; } .sbi-fb-embed-step-2 > div{ padding: 0 29px; } .sb-customizer-sidebar-cache-wrapper{ margin-top: 20px; padding: 0 20px; } .sbi-fb-embed-step-2-list{ margin-top: 25px; border-top: 1px solid #DCDDE1; padding-top: 14px !important; } .sbi-fb-embed-step-2-list > strong{ text-transform: uppercase; font-size: 12px; color: #434960; margin-bottom: 10px; } .sbi-fb-embed-step-2-pages{ margin-top: 8px; height: 250px; overflow: auto; } .sbi-fb-embed-step-2-pages .sb-control-toggle-icon svg { width: 11px; } .sbi-fb-embed-step-2-action{ padding: 10px 34px 10px 30px !important; background: #F3F4F5; box-shadow: 0px -4px 5px rgba(0, 0, 0, 0.1); } .sbi-fb-embed-step-2-action a{ color: #fff; } .sbi-fb-embed-step-2-action a[data-active="false"]{ opacity: .75; } /*Dialog Popup*/ .sbi-fb-dialog-remove-source{ background: #F3F4F5; padding: 40px 20px; display: flex; justify-content: center; align-items: center; } .sbi-fb-dialog-remove-source .sbi-fb-srcs-item{ background: #fff; width: 280px; padding-left: 20px; box-sizing: border-box; margin-top: 0px; } .sbi-fb-srcs-item-remove{ position: absolute; width: 35px; height: 35px; border-radius: 50px; background: #fff; border:1px solid #E7E7E9; z-index: 3; right: -13px; bottom: -13px; display: flex; justify-content: center; align-items: center; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); } .sbi-fb-srcs-item-remove svg{ width: 12px; float: left; fill: var(--error-red); } .sbi-fb-dialog-popup-content{ display: flex; justify-content: center; align-items: center; text-align: center; flex-direction: column; padding: 38px 12%; } .sbi-fb-dialog-popup-content strong{ font-size: 22px; color: #141B38; display: block; margin-bottom: 15px; } .sbi-fb-dialog-popup-content span{ font-size: 16px; line-height: 1.5em; color: #434960; } .sbi-fb-dialog-popup-actions{ display: flex; justify-content: center; align-items: center; margin-top: 25px; } .sbi-fb-dialog-popup-actions button{ width: 100%; margin: 4px 4px; cursor: pointer; height: 42px; } /* Footer Sticky Widget */ .sbi-stck-wdg{ position: fixed; right: 21px; z-index: 9; bottom: 20px; } .sbi-stck-wdg-btn{ width: 52px; height: 52px; background: #fff; border-radius: 50%; cursor: pointer; display: flex; justify-content: center; align-items: center; filter: drop-shadow(0px 9px 13px rgba(0, 0, 0, 0.2)); } .sbi-stck-wdg-btn svg{ width: 25px; fill: #FE544F; height: 33px; float: left; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn svg,.sbi-stck-wdg-btn-cls{ display: none; } .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls, .sbi-stck-wdg[data-active="true"] .sbi-stck-wdg-btn-cls svg{ display: block; } .sbi-stck-wdg-btn-cls{ width: inherit; height: inherit; position: relative; color: #364152; box-shadow: 0px 1px 6px rgba(0, 0, 0, .05), 0px 9px 12px rgba(0, 0, 0, .05); border-radius: 70px; } .sbi-stck-wdg-btn-cls svg { width: 14px; height: 14px; position: absolute; top: 50%; right: 0; bottom: 0; left: 50%; margin-top: -7px; margin-left: -7px; } .sbi-stck-pop{ position: absolute; width: 292px; height: auto; background: #fff; border: 1px solid #E2E8F0; box-sizing: border-box; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 3px 14px rgba(0, 0, 0, 0.12); border-radius: 2px; padding: 20px; right: 0px; bottom: 100px; color: #141B38; opacity: 0; padding-bottom: 82px; visibility: hidden; } .sbi-stck-wdg[data-active="true"] .sbi-stck-pop{ bottom: 66px; opacity: 1; visibility: visible; } .sbi-stck-pop svg{ fill: currentColor; } .sbi-stck-el-list{ border: 1px solid #DCDDE1; border-radius: 2px; } .sbi-stck-el{ display: flex; align-items: center; padding: 11px 13px; border-bottom: 1px solid #DCDDE1; } .sbi-stck-el:hover{ background: #F3F4F5; } .sbi-stck-el:last-of-type{ border-bottom: 0px; } .sbi-stck-el-list .sbi-chevron svg{ width: 5px; height: 8px; } .sbi-stck-el-list .sbi-stck-el-icon svg { } .sbi-stck-el .sbi-stck-el-txt{ color: #27303F; } .sbi-stck-el.sbi-stck-el-upgrd{ padding: 8px 14px; font-size: 14px; background: var(--cl-orange); color: #fff; } .sbi-chevron { position: absolute; right: 14px } .sbi-stck-el.sbi-stck-el-upgrd .sbi-stck-el-txt{ color: #fff; } .sbi-stck-el.sbi-stck-el-upgrd:after{ top: 20px; opacity: 1; } .sbi-stck-el-icon{ margin-right: 10px; } .sbi-stck-el-icon svg{ width: 17px; float: left; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } #sbi-builder-app .sbi-stck-title{ margin-top: 20px; margin-bottom: 10px; } .sbi-stck-follow{ background: #F3F4F5; margin-top: 20px; left: 0px; bottom: 0px; position: absolute; padding: 12px 20px; display: flex; align-items: center; } .sbi-stck-follow span{ font-weight: 600; font-size: 14px; } .sbi-stck-flw-links{ display: flex; justify-content: center; align-items: center; margin-left: auto; } .sbi-stck-flw-links a{ width: 36px; height: 28px; color: inherit; display: inline-flex; justify-content: center; align-items: center; margin-left: 4px; border-radius: 2px; } .sbi-stck-flw-links svg{ width: 17px; color: #141B38; } .sbi-stck-flw-links a:hover{ background: #fff; } .sbi-stck-flw-links a:hover svg{ color: inherit; } /* Builder Footer */ .sbi-bld-footer > div{ background: #fff; color: #141B38; margin: 30px 0; } .sbi-bld-footer{ padding-top: 0px!important } .sbi-bld-ft-content{ display: flex; align-items: center; max-width: 1200px; } .sbi-bld-ft-img{ float: left; width: 15%; margin-right: 5%; /*height: 158px;*/ } .sbi-bld-ft-img svg{ margin-bottom: -4px; } .sbi-bld-ft-txt{ display: flex; justify-content: center; align-items: center; width: 59%; margin-right: 5%; } .sbi-bld-ft-txt strong, .sbi-fb-mr-fd-heading span{ color: var(--cl-orange); } #sbi-builder-app .sbi-bld-ft-info{ width: 44%; color: #434960; } #sb-footer-banner .sbi-bld-ft-title{ width: 63%; margin-right: 6%; } .sbi-bld-ft-action{ width: 17%; display: flex; justify-content: left; align-items: center; } .sbi-bld-ft-action svg{ top: 14px; height: 10px; } @media all and (max-width: 1130px) { #sb-footer-banner .sbi-bld-ft-img{ width: 17%; margin-right: 3%; } #sb-footer-banner .sbi-bld-ft-txt{ display: flex; justify-content: center; align-items: center; width: 61%; margin-right: 3%; } #sbi-builder-app #sb-footer-banner h3 { font-size: 20px; } #sbi-builder-app #sb-footer-banner .sb-small-p { font-size: 13px; } #sb-footer-banner .sb-button-standard { font-size: 13px; padding-left: 16px; line-height: 15px; } } .sbi-bld-ft-btm{ font-size: 14px; display: flex; justify-content: center; align-items: center; padding: 15px 0px; border-top: 1px solid #DCDDE1; } .sbi-bld-ft-btm strong{ padding: 0 5px; } .sbi-bld-ft-btm a{ display: inline-block; padding: 0 10px; font-weight: 500; color: #0068A0; } .sbi-bld-ft-btm a i{ font-size: 12px; margin-left: 5px; } .sbi-bld-ft-bns{ display: inline-block; margin: 0 10px; padding: 5px 10px; border-radius: 5px; font-size: 14px; font-weight: 700; text-transform: uppercase; color: #663D00; background: #FFDF99; } /* Extensions Poup */ .sbi-fb-fs-link{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; right: 0; bottom: 0; z-index: 1; } .sbi-fb-extensions-popup{ } .sbi-fb-extpp-top{ display: flex; justify-content: center; align-items: center; height: 264px; background: #F3F4F5; } .sbi-fb-extpp-img{ width: 50%; float: left; display: flex; justify-content: center; } .sbi-fb-extensions-popup[data-getext-view="featuredpost"] .sbi-fb-extpp-img{ padding: 50px 0px; } .sbi-fb-extensions-popup[data-getext-view="singlealbum"] .sbi-fb-extpp-img{ padding: 65px 0px; } .sbi-fb-extpp-social-wall .sbi-fb-extpp-top { display: flex; flex-direction: column; align-items: center; height: auto; padding-top: 29px; } .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-fb-extpp-head { margin: 0 0 12px; padding-top: 14px; } .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-fb-extpp-head h2 { font-size: 24px !important; line-height: 120% !important; } .sbi-fb-extpp-info{ width: 50%; float: left; display: flex; justify-content: center; flex-direction: column; padding-left: 40px; } .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-fb-extpp-info { width: 40%; padding-right: 50px; } .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-fb-extpp-lite-btn { margin-top: 20px; max-width: 270px; box-sizing: border-box; padding: 7px 11px; } .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-extension-bullet-list { grid-template-columns: 33% 33% 33%; } #sbi-builder-app .sbi-fb-extensions-popup[data-getext-view="socialwall"] .sbi-fb-extpp-head{ margin: 0 0 9px; } #sbi-builder-app .sbi-fb-extpp-desc { color: #475569; display: flex; justify-content: center; align-items: center; } .sbi-fb-extpp-social-wall .sbi-fb-extpp-top { display: flex; flex-direction: column; align-items: center; height: auto; padding-top: 29px; } .sbi-fb-extpp-info{ width: 50%; float: left; display: flex; justify-content: center; flex-direction: column; padding-left: 40px; } .sbi-fb-extpp-info .sbi-fb-extpp-head, .sbi-fb-extpp-info .sbi-fb-extpp-desc{ width: 100%; } #sbi-builder-app .sbi-fb-extpp-head{ margin: 0 0 12px; } #sbi-builder-app .sbi-fb-extpp-desc { color: #475569; display: flex; justify-content: left; align-items: center; width: 105%; } .sbi-fb-extpp-head span{ color: var(--cl-orange); } .sbi-fb-extpp-head span.sb-social-wall{ color: inherit; font-size: 26px; line-height: 120% !important; display: inline-block; } .sbi-fb-extpp-desc .sb-social-wall { width: 90%; } .sbi-fb-extpp-head span{ color: var(--cl-orange); } .sbi-fb-extpp-lite-btn{ float: left; font-size: 15px; font-weight: 500; padding: 10px 20px; color: #0068A0; background: #fff; border: 1px solid #DCDDE1; margin-bottom: 14px; margin-top: 12px; align-items: center; } .sbi-fb-extpp-lite-btn svg{ fill: currentColor; width: 20px; float: left; margin-right: 10px; } .sbi-fb-extpp-inc-list{ border: 1px solid #dcdde1; margin-top: 10px; margin-bottom: 30px; } .sbi-fb-extpp-bottom-strg{ font-size:18px; font-weight: 600; } .sbi-fb-extpp-inc-items{ display: grid; grid-template-columns: 25% 25% 25% 25%; } .sbi-fb-extpp-inc-item, .sbi-fb-extpp-inc-item-bottom{ position: relative; height: 50px; display: flex; justify-content: center; align-items: center; border-right: 1px solid #dcdde1; border-bottom: 1px solid #dcdde1; font-size: 14px; } .sbi-fb-extpp-inc-item-bottom{ border: 0px !important; } .sbi-fb-extpp-inc-item:last-of-type{ border-right: 0px; } .sbi-fb-extpp-inc-item svg, .sbi-fb-extpp-inc-item-bottom svg{ width: 17px; margin-right: 10px; fill: currentColor; float: left; } .sbi-fb-extpp-bottom{ padding: 20px 40px; background: #fff; } .sbi-extension-bullet-list { display: grid; grid-template-columns: 33% 33% 33%; grid-column-gap: 2%; margin-top: 12px; margin-bottom: 40px; } .sbi-extension-single-bullet { display: flex; justify-content: flex-start; align-items: center; margin: 4px 0; } #sbi-builder-app .sbi-extension-single-bullet span { color: #434960; } .sbi-extension-single-bullet svg { margin-right: 12px; } .sbi-fb-extpp-btns{ display: grid; grid-template-columns: 100%; grid-column-gap: 1%; } .sbi-fb-extpp-btns div{ height: 38px; cursor: pointer; position: relative; border-radius: 3px; font-style: normal; font-weight: 600; font-size: 14px; line-height: 160%; display: flex; justify-content: center; align-items: center; box-sizing: border-box; } .sbi-fb-extpp-get-btn{ color: #fff; background: var(--cl-orange); } .sbi-fb-extpp-demo-btn{ border: 2px solid #DCDDE1; background: #F3F4F5; } /* Feed Type Creation Process : Single Album; */ .sbi-fb-section-wh-insd{ display: flex; } .sbi-fb-sglelm-inp-ctn{ margin-top: 100px; } .sbi-fb-sglelm-inp-ctn input[type="text"]{ height: 44px; } .sbi-fb-section-wh.sbi-fb-sglelm-ctn { padding: 20px 21px 24px 30px; } .sbi-fb-section-wh.sbi-fb-sglelm-ctn .sbi-fb-section-wh-insd { padding: 0; } .sbi-fb-sglelm-inp-ctn input[type="text"]::placeholder{ font-style: normal; font-weight: normal; font-size: 16px; line-height: 160%; color: #8C8F9A; } .sbi-fb-sglelm-error-icon{ width: 23px; height: 23px; background: var(--error-red); font-family: monospace; font-weight: 900; color: #fff; font-size: 15px; position: absolute; right: 10px; top: 10px; z-index: 999999999999999999; border-radius: 50px; display: flex; justify-content: center; align-items: center; } .sbi-fb-sglelm-errormsg{ color: var(--error-red); font-weight: 800; } .sbi-fb-sglelm-inp-ctn .sbi-fb-wh-inp{ margin-bottom: 10px; } .sbi-fb-sglelm-left{ padding-right: 100px; } .sbi-fb-sglelm-img-ctn{ background:#E8E8EB; height: 350px; display: flex; justify-content: center; align-items: center; text-align: center; flex-direction: column; padding: 100px 50px; border: 1px solid #D0D1D7; box-sizing: border-box; } .sbi-fb-sglelm-img-ctn.sbi-fb-sglelm-img-pf{ padding: 100px 35px; } .sbi-fb-sglelm-img-ctn strong{ font-size: 16px; color: #434960; margin-bottom: 8px; margin-top: 30px; } .sbi-fb-sglelm-img-ctn span{ font-size: 14px; line-height:1.6em; color: #8C8F9A; } .sbi-fb-sglelm-right{ width: 445px } .sbi-fb-sglelm-img-errorctn span{ padding: 0 20px; color: #434960; font-size: 20px; margin-top: 30px; line-height: 1.2em; } .sbi-fb-sglelm-preview{ height: 375px; background-color: #141B38; background-position: center center; background-size: cover; display: flex; justify-content: center; align-items: flex-end; color: #fff; } .sbi-fb-sglelm-preview:after{ content: ''; position: absolute; width: 100%; height: 100%; background-image: linear-gradient(to bottom, rgba(0,0,0,0) , rgba(0,0,0,.5)); } .sbi-fb-sglelm-prev-info{ width: 100%; padding: 20px 30px; padding-bottom: 40px; display: flex; justify-content: center; align-items: center; text-align: center; flex-direction: column; z-index: 2; } .sbi-fb-sglelm-prev-info strong{ font-size: 18px; margin-bottom: 5px; } .sbi-fb-sglelm-prev-info span{ font-size: 16px; line-height: 1.7em; } /* Feeds List */ #sbi-builder-app .sbi-fb-select, #sbi-builder-app .sbi-fb-select:hover, #sbi-builder-app .sbi-fb-select:focus{ border-radius: 0px!important; border: 1px solid #D0D1D7!important; outline: unset!important; float: left; min-height: auto; padding: 6px 31px 6px 8px; background: #fff url("data:image/svg+xml,%3Csvg width='10' height='5' viewBox='0 0 10 5' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.833252 0.333252L4.99992 4.49992L9.16658 0.333252H0.833252Z' fill='%238C8F9A'/%3E%3C/svg%3E%0A") no-repeat right 13px top 55%; background-size: 10px 6px; } .sbi-fd-lst-bulk-ctn > *{ float: left; margin-right: 10px; } .sbi-fd-lst-bulk-ctn{ margin-bottom: 8px; } .sbi-fd-lst-pagination-ctn{ float: right; display: flex; align-items: center; margin-top: 10px; } .sbi-fd-lst-pgnt-btn{ height: 30px; padding: 0 8px; cursor: pointer; border-radius: 3px; } .sbi-fd-lst-pgnt-info{ display: inline-block; padding: 0 3px; } .sbi-fd-lst-count{ margin-right: 10px; } .sbi-feeds-list table{ width: 100%; text-align: left; border-spacing: 0px; box-sizing: border-box; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); background: #fff; } .sbi-feeds-list table a{ cursor: pointer; } .sbi-fd-lst-tbody tr:nth-child(odd){ background: #F3F4F5; } .sbi-fd-lst-tbody tr td{ position: relative; vertical-align: top; padding: 12px 5px; font-size: 16px; } .sbi-feeds-list table tr td:first-child { width: 30px; } .sbi-fd-lst-thtf{ background: #fff; } .sbi-fd-lst-thtf th, .sbi-fd-lst-thtf td{ padding: 6px 5px; } .sbi-fd-lst-thtf th{ border-bottom: 1px solid #DCDDE1; } .sbi-fd-lst-thtf td{ border-top: 1px solid #DCDDE1; } .sbi-fd-lst-chkbx{ width: 11px; height: 11px; position: relative; border-radius: 2px; border: 1px solid #97A6BA; background: #fff; cursor: pointer; margin-left: 10px; } tbody .sbi-fd-lst-chkbx { position: absolute; top: 15px; left: 5px; bottom: 0; right: 0; } .sbi-fd-lst-thtf .sbi-fd-lst-chkbx{ width: 11px; height: 11px; border: 1px solid #D8DADD; } .sbi-fd-lst-chkbx[data-active="true"]{ background: var(--customizer-blue); border-color: var(--customizer-blue)!important; } .sbi-fd-lst-chkbx[data-active="true"]:before{ content: ''; position: absolute; width: 6px; height: 3px; left: 2px; top: 2px; border-bottom: 2px solid #fff; border-left: 2px solid #fff; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-fd-lst-name{ font-size: 17px; font-weight:500; color: #0068A0!important; } .sbi-fd-lst-type{ display: block; text-transform: capitalize; } .sb-instances-cell { margin-top: 4px; } .sbi-fd-lst-btn{ width: 21px; height: 21px; display: inline-flex; justify-content: center; align-items: center; margin: 0 4px; cursor: pointer; color: #141B38; border-radius: 2px; border: 1px solid #D8DADD; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; background: #fff; } .sbi-fd-lst-btn svg { height: 13px; } .sbi-fd-lst-actions .sbi-fd-lst-btn, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-btn{ box-sizing: border-box; width: 36px; height: 32px; background: transparent; } .sbi-fd-lst-actions .sbi-fd-lst-btn { margin: 0 4px 0 0; } .sbi-fd-lst-actions .sbi-fd-lst-btn:last-child { margin: 0; } .sbi-fd-lst-actions .sbi-fd-lst-btn svg { width: 12px; height: 16px; } .sbi-fd-lst-btn-delete{ color: #D72C2C; border-color: #FBD5D5; } .sbi-fd-lst-btn svg{ fill: currentColor; width: 14px; float: left; } .sbi-fd-lst-actions .sbi-fd-lst-btn:hover svg, .sbi-feedtype-section .sbi-fd-lst-btn-delete:hover svg{ color: #fff; } .sbi-fd-lst-actions .sbi-fd-lst-btn:hover{ background: #0096CC; border-color: #0096CC; } .sbi-fd-lst-actions .sbi-fd-lst-btn-delete:hover, .sbi-feedtype-section .sbi-fd-lst-btn-delete:hover{ background: #D72C2C; border-color: #D72C2C; } .sbi-fd-lst-dimmed .sbi-fd-lst-btn, .sbi-fd-lst-dimmed .sbi-fd-lst-btn:hover{ background: #F3F4F5!important; border-color:#D8DADD!important; color: #8C8F9A!important; } .sbi-fd-lst-dimmed .sbi-fd-lst-btn:hover svg{ color: #8C8F9A!important; } .sbi-fb-tltp-parent{ position: relative; } .sbi-fb-view-instances[data-active="true"]{ font-weight: 600; text-decoration: underline; cursor: pointer; line-height: 1em; } .sbi-fb-tltp-elem{ position: absolute; color: #fff; background: #434960; font-size: 14px; padding: 7px 10px; border-radius: 3px; font-weight:500; z-index: 9; text-align: center; opacity: 0; visibility: hidden; top: calc(-100% - 30px); left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-fb-tltp-elem span{ position: relative; z-index: 3; } .sbi-fb-tltp-elem:after{ content: ''; position: absolute; height: 10px; width: 10px; bottom: -5px; left: calc(50% - 5px); background: #434960; transform: rotate(-45deg); } .sbi-fb-tltp-parent:hover .sbi-fb-tltp-elem { top: calc(-100% - 20px); opacity: 1; visibility: visible; } .sbi-fd-lst-shortcode-cp{ margin-left: 10px; } .sbi-fd-lst-act-th{ width: 190px; max-width: 190px; } /* Feed Instance Popup */ .sbi-fb-popup-feedinst .sbi-fb-source-top{ display: flex; align-items: center; } .sbi-fb-popup-feedinst h5{ margin-bottom: 0px; float: left; font-size: 27px; } .sbi-fb-fdinst-type{ padding: 5px 5px; background: #E8E8EB; margin-left: 12px; float: left; } .sbi-fb-inst-tbl-ctn{ padding: 0 23px 63px; } .sbi-fb-inst-tbl-ctn table{ width: 100%; border-spacing: unset; box-sizing: border-box; border: 1px solid #DCDDE1; text-align: left; } .sbi-fb-inst-tbl-ctn tfoot,.sbi-fb-inst-tbl-ctn thead{ background: #F3F4F5 } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf th, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf td{ font-size: 13px; color: #364152; padding: 13px 10px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr:nth-child(odd){ background: #fff; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr:nth-child(even){ background: #F3F4F5; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf tr th, .sbi-fb-inst-tbl-ctn .sbi-fd-lst-thtf tr td{ padding: 4px 20px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-tbody tr td{ padding: 11px 20px; } .sbi-fb-inst-tbl-ctn .sbi-fd-lst-name{ font-size: 14px; } .sbi-fb-inst-tbl-shrtc{ display: flex; align-items: center; } .sbi-fd-inst-btn{ width: 10px; height: 10px; box-sizing: border-box; border-right: 3px solid #8C8F9A; border-top: 3px solid #8C8F9A; cursor: pointer; -webkit-transform: rotate(45deg); transform: rotate(45deg); } /*Legacy Feeds */ .sbi-fb-lgc-top-new{ color: #141B38; background: #fff; margin: 10px 0px; padding: 15px 20px; display: flex; justify-content: center; align-items: center; font-size: 14px; font-weight: 600; } .sbi-fb-lgc-gr{ font-size: 12px; text-transform: uppercase; font-weight: 500; background: #59AB46; color: #fff; margin-right: 10px; padding: 6px 10px; border-radius: 2px; line-height: 1em; } .sbi-fb-lgc-inf-ctn{ background: #fff; padding: 0 20px; display: flex; align-items: center; height: 58px; } .sbi-fb-lgc-inf-ctn > h4{ margin-right: 10px!important; } .sbi-fb-lgc-inf-ctn > *{ float: left; display: inline-block; position: relative; } #sbi-builder-app .sbi-fb-lgc-inf-ctn > h4{ margin-right: 14px; margin-bottom: 0; } #sbi-builder-app .sbi-fb-lgc-btn-stg{ display: flex; margin-left: auto; } .sbi-fd-legacy-feed-toggle{ height: 34px; display: flex; justify-content: center; align-items: center; background: #E2F5FF; color:#0068A0; cursor: pointer; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-fd-legacy-feed-toggle:hover { background: #BFE8FF; } .sbi-fd-legacy-feed-toggle span{ display: inline-block; position: relative; padding-right: 20px; margin-left: -20px; } .sbi-fd-legacy-feed-toggle[data-active="true"] span:after{ -webkit-transform: rotate(-225deg); transform: rotate(-225deg); top: 7px; } .sbi-feeds-list .sbi-legacy-table-wrap table{ box-shadow: none; border-top: 1px solid #DCDDE1; } .sbi-fb-lgc-ctn{ box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); margin-bottom: 20px; } .sbi-fb-onbrd-infotxt{ display: flex; align-items: center; } .sbi-fb-onbrd-infotxt svg{ fill: currentColor; width: 16px; display: inline-block; margin-left: 10px; float: left; } .sbi-fb-onbrd-tltp-parent{ position: relative; } .sbi-fb-onbrd-tltp-elem{ position: absolute; z-index: 9; background: #fff; border-radius: 2px; color: #434960; padding: 16px 52px 4px 24px; font-size: 15px; left: -30px; top: calc(100% + 20px); line-height: 1.7em; box-shadow: 0px 1px 18px rgba(0,0,0,.2); display: none; } .sbi-fb-onbrd-tltp-elem[data-active="false"]{ display: none; } .sbi-fb-onbrd-tltp-elem[data-active="true"], .sbi-fb-onbrd-tltp-hover:hover .sbi-fb-onbrd-tltp-elem{ display: block; min-width: 440px; padding-bottom: 15px; } .sbi-fb-onbrd-tltp-elem .sb-pointer { position: absolute; left: 85px; top: -17px; } .sbi-fb-onbrd-tltp-elem-2 .sb-pointer { left: 485px; } .sbi-fb-onbrd-tltp-elem:after{ background: #fff; z-index: 999; top: 0px; margin-left: -10px; width: 40px; box-shadow: unset; -webkit-transform: rotate(0deg); transform: rotate(0deg); } .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem{ left: 50%; -webkit-transform:translateX(-50%); transform:translateX(-50%); bottom: calc(100% + 15px); top: unset; padding: 8px 11px; width: 100%; text-align: center; box-shadow: 0 5px 9px rgba(0,0,0,.2), 0 -4px 9px rgba(0,0,0,.1); } .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem:before { content: ''; position: absolute; left: 50%; bottom: -10px; border-top: 12px solid #fff; border-right: 12px solid transparent; border-left: 12px solid transparent; -webkit-transform: translateX(-50%); transform: translateX(-50%); z-index: 2; } .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem:before, .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem:after{ left: calc(50% - 10px); top: unset; } .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem:before{ bottom: -10px; } .sbi-fb-onbrd-tltp-parent.sbi-fb-onbrd-tltp-center-top .sbi-fb-onbrd-tltp-elem:after{ bottom: 0px; } #sbi-builder-app .sbi-fb-onbrd-tltp-txt{ margin: 0px; } .sbi-fb-onbrd-tltp-txt:last-of-type{ margin-bottom: 0px; } .sbi-fb-onbrd-tltp-elem .sbi-fb-popup-cls{ top: 12px; right: 16px; } [data-tltp-pos*="right"] .sbi-fb-onbrd-tltp-elem{ right: 50px; left: unset; } [data-tltp-pos*="right"] .sbi-fb-onbrd-tltp-elem:before, [data-tltp-pos*="right"] .sbi-fb-onbrd-tltp-elem:after{ left: unset; right: 13% } [data-tltp-pos*="right"] .sbi-fb-onbrd-tltp-elem:after{ margin-left: unset; margin-right: -10px; } .sbi-fd-lst-dimmed .sbi-fb-onbrd-tltp-elem{ top: 100%; } .sbi-fb-cp-clpboard{ width: 0px; height: 0px; position: absolute; left: -100000px; } .sbi-fb-copied{ position: fixed; z-index: 9999999; background: #010101; color: #fff; line-height: 1em; font-size: 15px; font-weight: 500; padding: 10px 20px; opacity: 0; visibility: hidden; -webkit-transition: all .2s ease-in-out, opacity .4s ease-in-out; transition: all .2s ease-in-out, opacity .4s ease-in-out; left: 50%; bottom: -20px; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .sbi-fb-copied[data-active="true"]{ opacity: 1; visibility: visible; bottom: 20px; } /* **** customizer Screens **** */ .sb-customizer-ctn{ /*margin-top: 52px;*/ min-height: 100vh; } .sb-customizer-sidebar{ position: fixed; z-index: 100; width: 375px; box-shadow: 4px 0px 14px rgba(0, 0, 0, .05), 1px 0px 4px rgba(0, 0, 0, .1); background: #fff; left: 160px; top: 96px; overflow: auto; bottom: 0px; padding-bottom: 50px; } .jetpack-masterbar .sb-customizer-sidebar { left: 272px; } body.folded .sb-customizer-sidebar{ left: 36px; } .sb-customizer-sidebar-tab-ctn{ display: flex; justify-content: center; align-items: center; margin-bottom: 24px; } .sb-customizer-sidebar-tab{ width: 50%; height: 56px; background: #F3F4F5; border-bottom: 2px solid #F3F4F5; display: flex; justify-content: center; align-items: center; cursor: pointer; } .sb-customizer-sidebar-tab[data-active="true"]{ border-color: #0096CC; } .sb-customizer-sidebar-tab:hover { background: #fff!important; color: #141B38!important; } .sb-customizer-sidebar-sec-el{ height: 52px; cursor: pointer; display: flex; align-items: center; color: #141B38; border-bottom: 1px solid #DCDDE1; -webkit-transition: background .2s ease-in-out; transition: background .2s ease-in-out; padding: 0 20px; } .sb-customizer-sidebar-sec-el:hover{ background: #F3F4F5; border-bottom: 1px solid #F3F4F5; } .sb-customizer-sidebar-sec-el .sb-customizer-chevron svg{ position: absolute; right: 22px; top: 22px; } .sb-customizer-sidebar-sec-el-icon{ margin-right: 15px; width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; } .sb-customizer-sidebar-sec-el-icon svg{ width: 20px; float: left; fill: currentColor; } .sb-customizer-sidebar-sec-elhead{ height: 50px; padding: 0 20px; display: flex; align-items: center; margin-top: 30px; font-style: normal; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; color: #8C8F9A; } .sb-customizer-sidebar-header{ padding: 20px 20px; border-bottom: 1px solid #DCDDE1; } .sb-customizer-sidebar-header[data-separator="none"]{ border-bottom: 0px!important; padding-bottom: 0px; } .sb-customizer-sidebar-breadcrumb{ margin-bottom: 15px; } .sb-customizer-sidebar-sec1 a:hover{ text-decoration: underline; cursor: pointer; } .sb-breadcrumb-pro-label{ color: #fff !important; display: inline-block; background: var(--cl-orange); padding: 5px 8px; font-size: 11px; line-height: 1em !important; border-radius: 4px; -webkit-transform: translateX(5px) translateY(-4px); transform: translateX(8px) translateY(-2px); } .sb-control-elem-label .sb-breadcrumb-pro-label{ -webkit-transform: translateX(5px) translateY(0px); transform: translateX(5px) translateY(0px); } .sb-customizer-sidebar-breadcrumb a, .sb-customizer-sidebar-breadcrumb span{ display: inline-block; position: relative; cursor: pointer; color: #434960; text-transform: uppercase; font-size: 10px; line-height: 160%; letter-spacing: 0.08em; padding: 0 17px; height: 20px; font-weight: 600; } .sb-customizer-sidebar-breadcrumb span{ cursor: text; } .sb-customizer-sidebar-breadcrumb svg { position: absolute; left: 4px; top: 6px; } .sb-customizer-sidebar-header strong{ font-size: 26px; color: #141B38; display: block; margin-bottom: 10px; line-height: 1.1em; } .sb-customizer-sidebar-header span{ line-height: 1em; color: #434960; } .sb-customizer-sidebar-intro { display: block; padding: 5px 0 10px 0; line-height: 1.7 !important; } .sb-customizer-ctrl-link{ text-decoration: underline!important; } /* Controls Style */ .sb-control-label[data-title="true"]{ font-weight: 600; } .sb-control-elem-ctn{ display: flex; color: #141B38; padding: 20px 20px; } .sb-control-elem-ctn[data-stacked="true"]{ padding: 5px 20px; } .sb-control-elem-ctn[data-type="heading"]{ padding-bottom: 0; } .sb-control-elem-overlay{ width: 100%!important; height: 100%!important; position: absolute!important; left: 0!important; top: 0!important; z-index: 5!important; background: rgba(255,255,255,0.4)!important; } #sbi-builder-app .sb-control-elem-ctn[data-type="heading"] .sb-small-p{ font-weight: 600; } #sbi-builder-app .sb-control-elem-ctn[data-type="heading"] .sb-control-elem-description{ font-style: normal; font-weight: normal; font-size: 12px; line-height: 150%; color: #434960; } #sbi-builder-app .sb-control-elem-ctn[data-type="heading"] .sb-control-elem-label { margin-bottom: 0; } .sb-control-elem-heading svg { margin-left: 8px; } .sb-control-elem-ctn[data-separator="top"],.sb-control-elem-ctn[data-separator="both"]{ border-top: 1px solid #DCDDE1; } .sb-control-elem-ctn[data-separator="bottom"],.sb-control-elem-ctn[data-separator="both"]{ border-bottom: 1px solid #DCDDE1; } .sb-control-elem-ctn[data-type="separator"]{ padding: 0; } .sb-control-elem-separator{ height: 2px; border-top: 1px solid #DCDDE1; } .sb-control-elem-ctn[data-reverse="true"]{ flex-direction: row-reverse; } .sb-control-elem-ctn svg{ fill: currentColor; } .sb-control-elem-output{ padding-left: 20px; } .sb-control-elem-ctn[data-reverse="true"] .sb-control-elem-output{ padding-right: 20px; padding-left: 0px; } .sb-control-elem-ctn[data-layout="block"]{ display: block; } .sb-control-elem-ctn[data-layout="block"] .sb-control-elem-label{ width: 100%; float: left; margin-bottom: 8px; } .sb-control-elem-ctn[data-layout="block"] .sb-control-elem-output{ padding: 0px; } .sb-control-elem-ctn[data-layout="block"] input[type="number"] { height: 36px; background: #FFFFFF; border-radius: 1px 0 0 1px !important; /*border-right-color: #F3F4F5 !important;*/ } .sb-control-elem-ctn[data-layout="block"] [data-contains-suffix="true"] input[type="number"]{ border-right-color: #F3F4F5 !important; } .sb-control-elem-ctn[data-child="true"]{ padding-left: 70px; } .sb-control-elem-ctn[data-layout="half"]{ align-items: center; justify-content: flex-start; } .sb-control-elem-ctn[data-layout="half"][data-switcher-top="true"]{ align-items: flex-start!important; } .sb-control-elem-ctn[data-layout="half"][data-switcher-top="true"] .sb-control-switcher-ctn{ margin-top: 5px; } .sb-control-elem-ctn[data-layout="half"] > div{ width: 100%; } .sb-control-elem-ctn[data-type="switcher"][data-reverse="true"][data-layout="half"] > div{ width: unset; } .sb-control-elem-ctn[data-layout="half"][data-reverse="true"]{ justify-content: flex-end; } [data-type="switcher"][data-reverse="true"][data-layout="half"] .sb-control-elem-output{ padding-right: 5px; } .sb-control-elem-label-title{ display: flex; align-items: center; } .sb-control-elem-description{ color: #434960; font-size: 13px; float: left; margin-top: 4px; } .sb-control-elem-description a{ cursor: pointer; } .sb-control-elem-ctn[data-heading="strong"] .sb-control-elem-heading{ font-weight: 500!important; } .sb-control-elem-heading[data-underline="true"]{ text-decoration: underline; } .sb-control-elem-icon{ display: flex; justify-content: center; align-items: center; } .sb-control-elem-icon svg{ width: 16px; float: left; margin-right: 10px; } .sb-control-elem-tltp{ margin-left: 10px; position: relative; } .sb-control-elem-tltp-icon{ float: left; cursor: pointer; } .sb-control-elem-tltp-icon svg{ width: 14px; float: left; } /*Switcher Control*/ .sb-control-switcher-ctn{ cursor: pointer; display: flex; align-items: center; float: left; } .sb-control-switcher{ width: 36px; height: 18px; border-radius: 25px; background: #D0D1D7; position: relative; margin-right: 10px; } .sb-control-switcher:before{ content: ''; position: absolute; height: 14px; width: 14px; left: 3px; top: 2px; border-radius: 25px; background: #fff; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.25); -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sb-control-switcher-ctn[data-active="true"] .sb-control-switcher{ background: var(--customizer-blue); } .sb-control-switcher-ctn[data-active="true"] .sb-control-switcher:before{ left: 19px; } /*Toggle SINGLE Control*/ .sb-control-toggle-elm{ display: flex; align-items: center; cursor: pointer; height: 46px; padding: 0 15px; border-right: 1px solid #E8E8EB; border-left: 1px solid #E8E8EB; border-bottom: 1px solid #E8E8EB; } .sb-control-toggle-elm:first-child { border-top: 1px solid #E8E8EB; } .sb-control-toggle-elm[data-disabled="true"]{ background: #F3F4F5; } .sb-control-toggle-extension-cover{ width: 100%; height: 100%; position: absolute; left: 0px; top: 0; cursor: pointer; z-index: 4; } .sb-control-toggle-deco{ width: 16px; height: 16px; margin-right: 13px; box-sizing: border-box; border-radius: 50%; border: 2px solid #d0d1d7; } .sb-control-toggle-icon{ display: flex; justify-content: center; align-items: center; margin-right: 13px; } .sb-control-toggle-icon svg{ width: 16px; float: left; fill: #141B38; } .sb-control-toggle-elm[data-active="true"]{ background: #F7FDFF; border-radius: 2px; border: 1px solid var(--customizer-blue); } .sb-control-toggle-elm[data-active="true"]{ background: #F7FDFF; border-radius: 2px; border: 1px solid var(--customizer-blue); } .sb-control-toggle-elm:hover:not(.sb-control-toggle-elm[data-disabled="true"]) .sb-control-toggle-deco, .sb-control-toggle-elm[data-active="true"]:not(.sb-control-toggle-elm[data-disabled="true"]):hover .sb-control-toggle-deco{ border: 4px solid var(--customizer-blue); background: #fff; } .sb-control-toggle-elm[data-active="true"] .sb-control-toggle-deco{ border: 6px solid var(--customizer-blue); background: #fff; } /*Toggle SET Control*/ .sb-control-toggle-set-ctn .sb-control-toggle-elm[data-active="true"]{ border-radius: 0px; } /*Toggle Button Control*/ .sb-control-togglebutton-ctn{ display: flex; align-items: center; justify-content: center; padding: 3px; background: #f3f4f5; border-radius: 4px; border: 1px solid #eee; height: 40px; } .sb-control-togglebutton-elm{ width: 100%; display: flex; justify-content: center; align-items: center; height: 33px; cursor: pointer; font-weight: 600; border-radius: 4px; text-transform: capitalize; line-height: 1em; } .sb-control-togglebutton-elm[data-active="true"]{ color: var(--dark-blue); background: #fff; } .sb-control-togglebutton-elm:hover{ color: var(--dark-blue); } .sb-control-toggle-set-desc-ctn .sb-control-label{ font-weight: 600; } .sb-control-toggle-set-desc-ctn .sb-control-toggle-elm{ height: 82px; } .sb-control-toggle-set-desc-ctn .sb-control-toggle-deco{ flex-grow: 0; flex-shrink: 0; } .sb-control-moderatiomode-selement .sb-control-elem-label-title{ margin-bottom: 15px; } .sb-control-moderatiomode-selement{ margin-bottom: 20px; padding: 20px 0px; } /*Input Control*/ .sb-control-input-ctn{ display: flex; } .sb-control-input,.sb-control-input-textrea{ height: 40px; background: #fff; border: 1px solid #D0D1D7!important; border-radius: unset!important; outline: unset!important; padding: 0 10px!important; line-height: 1em; margin: 0px; } .sb-control-input-textrea{ padding: 10px!important; height: 120px; line-height: 1.5em; } .sb-control-input:hover{ color: inherit!important; } .sb-control-input:focus,.sb-control-input-textrea:focus{ border: 1px solid #8C8F9A!important; border-radius: unset!important; box-shadow: unset!important; outline: unset!important; } .sb-control-input[disabled],.sb-control-input-textrea[disabled]{ background-color: #F3F4F5; border: 1px solid #E8E8EB; } .sb-control-input-info{ display: flex; justify-content: center; align-items: center; background: #F3F4F5; padding: 0 8px; font-weight: normal; font-size: 14px; line-height: 160%; color: #434960; border: 1px solid #D0D1D7; border-left: none; border-radius: 0 1px 1px 0 !important; } /*ImageChooser Control*/ .sb-control-imagechooser-ctn{ display: flex; background: #F3F4F5; border: 1px solid #ccc!important; height: 40px; } .sb-control-imagechooser-input, .sb-control-imagechooser-input:focus{ outline: none!important; border: none!important; box-shadow: none!important; background: none!important; height: 40px; } .sb-control-imagechooser-btn svg{ width: 18px; margin-right: 5px; float: left; } .sb-control-imagechooser-btn{ display: flex; justify-content: center; align-items: center; padding: 0 10px; cursor: pointer; border-left: 1px solid #ccc!important; font-weight: 500; color: #141B38; } .sb-control-imagechooser-clear{ position: absolute; right: 4px; top: 10px; } .sb-control-imagechooser-clear-icon{ position: relative; width: 20px; height: 20px; color: #141B38; cursor: pointer; opacity: 0.5; } .sb-control-imagechooser-clear-icon:hover{ opacity: 1; } .sb-control-imagechooser-clear-icon:before, .sb-control-imagechooser-clear-icon:after{ content: ''; position: absolute; width: 16px; height: 2px; background: currentColor; left: 2px; top: 9px; -webkit-transform:rotate(45deg); transform:rotate(45deg); } .sb-control-imagechooser-clear-icon:after{ -webkit-transform:rotate(-45deg); transform:rotate(-45deg); } .sb-control-imagechooser-padding{ padding-right: 31px!important; } /*CheckBox Control*/ .sb-control-checkbox-ctn{ cursor: pointer; display: flex; } [data-disabled="true"] .sb-control-checkbox{ z-index: -1!important; } .sb-control-checkbox{ width: 18px; height: 18px; border-radius: 2px; float: left; border: 2px solid #D0D1D7; box-sizing: border-box; position: relative; margin-right: 10px; flex: none; } .sb-control-checkbox-ctn > div{ z-index: 3; } .sb-control-checkbox-ctn:hover .sb-control-checkbox-hover{ opacity: 1; } .sb-control-checkbox-hover{ position: absolute; left: -20px; top: 0px; width: calc(100% + 40px); height: 100%; background:#F3F4F5; z-index: 1; opacity: 0; } .sb-control-checkbox{ z-index: 5!important; } .sb-control-checkbox[data-active="true"]{ background: var(--customizer-blue); border-color: var(--customizer-blue); color: #fff; } .sb-control-checkbox[data-active="true"]:before{ content: ''; position: absolute; width: 8px; height: 4px; top: 2px; left: 2px; border-left: 2px solid currentColor; border-bottom: 2px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } /*Action Button Control*/ .sb-control-action-button{ height: 38px; cursor: pointer; display: flex; flex-direction: row; justify-content: center; align-items: center; background: #F3F4F5; border-radius: 2px; border: 1px solid #DCDDE1; position: relative; line-height: 1em; margin-top: 7px; } .sb-control-action-button div{ float: left; width: 20px; height: 20px; display: flex; justify-content: center; align-items: center; margin-right: 8px; } .sb-control-action-button svg{ width: 17px; } /* WPColorPicker Control Redesign */ .sb-control-colorpicker-ctn .wp-picker-default{ display: none!important; } .sb-control-colorpicker-ctn .minicolors-theme-default.minicolors{ width: 100%; } .sb-control-colorpicker-ctn .minicolors-theme-default.minicolors-position-right .minicolors-swatch { /* left: auto; right: 6px; top: 6px; width: 26px; height: 26px; background: #F9F9FA; border: 0px; */ left: auto; right: 1px; top: 1px; width: 35px; height: 35px; background: #F9F9FA; border: 0px; } .minicolors-swatch-color{ box-shadow: none; } .sb-control-colorpicker-ctn .minicolors-input,.sb-control-colorpicker-ctn .minicolors-input:focus{ height: 37px; width: 100%!important; background: #fff; border: 1px solid #D0D1D7!important; border-radius: unset!important; outline: unset!important; box-shadow: unset!important; padding: 0 10px!important; line-height: 1em; margin: 0px; } .sb-control-colorpicker-ctn .minicolors-input:focus{ border: 1px solid #0096CC!important; } [data-type="colorpicker"] .minicolors-input{ font-size: 13px; } [data-type="colorpicker"] .minicolors-input{ font-style: normal; font-weight: normal; font-size: 12px; line-height: 150%; color: #434960; } .sb-control-colorpicker-btn{ height: 38px; display: flex; justify-content: center; align-items: center; border: 1px solid #DCDDE1; border-left: 0px; padding: 0 10px; background: #F3F4F5; font-style: normal; font-weight: 600; font-size: 12px; line-height: 160%; color: #141B38; cursor: pointer; box-sizing: border-box; } .sb-control-colorpicker-ctn[data-picker-style="reset"] .minicolors-input, .sb-control-coloroverride-ctn{ background: #F3F4F5!important; border: 1px solid #DCDDE1!important; } .sb-control-colorpicker-ctn[data-picker-style="reset"] .minicolors-theme-default.minicolors-position-right .minicolors-swatch, .sb-control-coloroverride-ctn .sb-control-coloroverride-swatch{ top: 8px; width: 22px; height: 22px; } .sb-control-coloroverride-ctn .sb-control-coloroverride-swatch{ position: absolute; right: 10px; } .sb-control-coloroverride-ctn .sb-control-colorpicker-btn{ margin-left: auto; border: 0px!important; border-left: 1px solid #DCDDE1!important; } .sb-control-coloroverride-ctn .sb-control-coloroverride-content{ width: 100%; display: flex; align-items: center; position: relative; } .sb-control-coloroverride-ctn .sb-control-coloroverride-txt{ padding-left: 9px; box-sizing: border-box; } /* Customizer Preview */ .sb-customizer-preview{ min-height: 100px; width: calc(100% - 375px); float: right; box-sizing: border-box; padding: 0 20px; display: flex; justify-content: center; margin-top: 64px; position: relative; flex-wrap: wrap; } .sb-customizer-preview .sbi-admin-notices{ margin-top: 20px; width: 100%; } .sb-customizer-preview .license-details-modal .sbi-modal-content { max-height: none; height: auto; } .sb-customizer-preview .sbi-sb-modal-body .sb-why-renew-list:nth-child(3) { margin-bottom: 0; } .sb-customizer-preview .sbi-sb-modal-body .sb-why-renew-list:last-child { margin-bottom: 0; } .sb-customizer-preview[data-preview-device="desktop"] .sb-preview-ctn{ width: 100%; max-width: 1200px; } .sb-customizer-preview[data-preview-device="tablet"] .sb-preview-ctn{ max-width: 100%; width: 800px; } .sb-customizer-preview[data-preview-device="mobile"] .sb-preview-ctn{ max-width: 100%; width: 400px; } .sbi-preview-ctn { padding: 10px; } .sb-preview-top-chooser{ padding: 18px 0 16px; display: flex; color: #434960; align-items: center; } .sb-preview-top-chooser strong{ font-style: normal; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; color: #434960; display: inline-flex; } .sbi-moderate-heading{ margin-top: 21px; } .sb-preview-top-chooser strong > svg{ margin-right: 10px; margin-left: 16px; fill: currentColor; width: 20px; } .sb-preview-chooser{ height: 36px; background: #E8E8EB; margin-left: auto; padding: 0 2px; border-radius: 1px; display: flex; justify-content: center; align-items: center; } .sb-preview-chooser-btn,.sb-preview-chooser-btn:focus{ width: 40px; height: 32px; display: flex; justify-content: center; align-items: center; cursor: pointer; float: left; border: 0; background: unset; outline: none; } .sb-preview-chooser-btn svg{ width: 15px; fill: currentColor; float: left; } .sb-preview-chooser-btn.sb-mobilee svg{ width: 9px; fill: currentColor; float: left; } .sb-preview-chooser-btn[data-active="true"], .sb-preview-chooser-btn:hover{ background: #fff!important; box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.25); border-radius: 1px; } .sb-control-checkboxsection-header{ width: 100%; margin-top: 25px; display: flex; align-items: center; text-transform: uppercase; font-size: 13px; padding-bottom: 15px; position: relative; } .sb-control-checkboxsection-header:before{ content: ''; position: absolute; left: -20px; width: calc(100% + 40px); height: 1px; background: #DCDDE1; bottom: 0px; } .sb-control-checkboxsection-name{ display: flex; align-items: center; } .sb-control-checkboxsection-header svg{ width: 20px; margin-right: 7px; fill: #434960; float: left; } .sb-control-checkboxsection-header > strong{ margin-left: auto; } [data-type="checkboxsection"] .sb-control-checkbox-ctn{ align-items: center; height: 50px; } [data-type="checkboxsection"] { padding: 0 20px !important; } [data-type="checkboxsection"] .sb-control-elem-label{ display: none; } [data-type="checkboxsection"] strong{ color: #434960 } [data-type="checkboxsection"] [data-active="true"] strong{ color: #141B38; } .sb-control-checkboxsection-btn{ width: 21px; height: 21px; position: relative; cursor: pointer; } .sb-control-checkboxsection-btn:before{ content: ''; position: absolute; width: 7px; height: 7px; left: 5px; top: 7px; border-right: 2px solid #8C8F9A; border-bottom: 2px solid #8C8F9A; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } /*CheckBox List*/ [data-type="checkboxlist"] .sb-control-checkbox-ctn{ margin-bottom: 10px!important; } [data-type="checkboxlist"] .sb-control-checkbox-ctn .sb-control-label{ font-style: normal; font-weight: normal; font-size: 14px; line-height: 160%; } /*Source Controls*/ .sb-control-sources-ctn .sbi-fb-srcs-item{ box-sizing: border-box; position: relative; cursor: auto; display: block; height: auto; border: 1px solid #E7E7E9; min-height: 60px; overflow: auto; margin-top: 0px; } .sbi-fb-srcs-item-ins{ cursor: pointer; display: flex; height: 62px; padding: 0 10px; position: relative; } .sb-control-src-icon{ width: 20px; height: 20px; position: absolute; right: 10px; top: 10px; z-index: 2; cursor: pointer; display: flex; justify-content: center; align-items: center; } .sb-control-src-icon svg{ width: 13px; float: left; } [data-expanded="true"] .sb-control-src-expand svg,.sbi-fb-srcs-info { display: none } .sb-control-src-expand-chevron{ width: 7px; height: 7px; border-left: 2px solid currentColor; border-top: 2px solid currentColor; -webkit-transform: rotate(45deg); transform: rotate(45deg); display: none; } [data-expanded="true"] .sb-control-src-expand-chevron,[data-expanded="true"] .sbi-fb-srcs-info { display: block; } .sb-control-src-remove svg{ width: 11px; fill: var(--error-red); } .sb-control-sources-ctn[data-multifeed="true"] .sb-control-src-expand { right: 30px; } .sb-control-elem-output .sb-control-src-expand:hover { background: #F3F4F5; border-radius: 3px; } .sb-control-elem-output .sb-control-src-expand:hover path{ fill: #111; } .sb-control-sources-ctn .sbi-fb-srcs-item .sbi-fb-srcs-item-name{ font-size: 17px; line-height: 1em; margin-bottom: 3px; } .sbi-fb-srcs-info-item{ display: flex; border-top: 1px solid #E7E7E9; box-sizing: border-box; width: 100%; float: left; padding: 8px 10px; } .sbi-fb-srcs-info-item:first-of-type{ align-items: center; } .sbi-fb-srcs-info-item strong{ font-size: 14px; width: 50px; } .sbi-fb-srcs-info-item span{ font-size: 13px; line-height: 1.1em; color: #434960; font-weight: 400; display: inline-block; word-break: break-all; width: calc(100% - 80px); padding: 0 15px; box-sizing: border-box; } .sbi-fb-srcs-info-icon{ width: 26px; height: 26px; display: flex; justify-content: center; align-items: center; cursor: pointer; margin-left: auto; border: 1px solid #D0D1D7; border-radius: 2px; } .sbi-fb-srcs-info-icon svg{ width: 15px; float: left; } .sb-control-sources-ctn .sb-control-action-button{ margin-top: 8px; margin-bottom: 16px; } .sb-control-sources-promo-ctn{ padding: 16px 0; } .sb-control-sources-promo-ctn:before{ content: ''; position: absolute; height: 1px; width: calc(100% + 40px); left: -20px; top: 0px; background: #E7E7E9; } .sb-control-sources-promo-top{ width: 100%; box-sizing: border-box; padding: 30px 20px; border: 1px solid #E8E8EB; float: left; background: #F9F9FA; } .sb-control-sources-promo-top > div{ width: 100%; float: left; text-align: center; display: flex; justify-content: center; align-items: center; box-sizing: border-box; line-height: 1.6em; } .sb-btn-chevron{ display: inline-block; width: 7px; height: 7px; border-right: 2px solid currentColor; border-top: 2px solid currentColor; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sb-control-sources-promo-text{ font-size: 15px; font-weight: 600; } .sb-control-sources-promo-btn{ display: flex; align-items: center; justify-content: center; padding: 16px 20px; color: #fff !important; background: #0068A0; font-size: 15px; } .sb-control-sources-promo-btn div{ margin-left: 10px; } .sb-control-sources-promo-icon{ margin-bottom: 20px; } /*Loading Bar*/ .sb-loadingbar-ctn{ position: absolute; height: 5px; width: 100%; left: 0px; bottom: 0px; background: rgba(227, 79, 14, 0.25); z-index: 999999999999999; } .sb-loadingbar-ctn:before, .sb-loadingbar-ctn:after{ content: ''; position: absolute; height: 5px; background: #FE544F; z-index: 9; top: 0; } .sb-loadingbar-ctn:before{ -webkit-animation: sbi-loading-animation 4s infinite; animation: sbi-loading-animation 4s infinite; } .sb-loadingbar-ctn:after{ -webkit-animation: sbi-loading-animation 4s 2s infinite; animation: sbi-loading-animation 4s 2s infinite; } @-webkit-keyframes sbi-loading-animation { from { left: -5%; width: 0%; } to { left: 130%; width: 50%;} } @keyframes sbi-loading-animation { from { left: -5%; width: 0%; } to { left: 130%; width: 50%;} } /*Notification Element*/ .sb-notification-ctn{ position: fixed; bottom: -100px; left: 200px; z-index: 99999; background: #fff; display: flex; justify-content: center; align-items: center; border-left: 3px solid #fff; line-height: 1em; padding: 10px 20px; padding-left: 0px; border-radius: 4px; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); } .sb-notification-ctn[data-active="hidden"]{ -webkit-animation: sbi-notification-hide .5s forwards linear; animation: sbi-notification-hide .5s forwards linear; } .sb-notification-ctn[data-active="shown"]{ -webkit-animation: sbi-notification-show .5s forwards linear; animation: sbi-notification-show .5s forwards linear; } @-webkit-keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @keyframes sbi-notification-show { 0%{bottom: -100px;} 50%{bottom: 70px;} 70%{bottom: 60px;} 85%{bottom: 65px;} 100%{bottom: 50px;}} @-webkit-keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} @keyframes sbi-notification-hide {0%{bottom: 50px;}55%{bottom: 65px;}70%{bottom: 60px;}85%{bottom: 70px;}100%{bottom: -100px;}} .sb-notification-ctn[data-type="success"]{ border-color: #59AB46; } .sb-notification-ctn[data-type="error"]{ border-color: #D72C2C; } .sb-notification-ctn[data-type="message"]{ border-color: #141B38; } .sb-notification-icon{ width: 25px; height: 25px; display: flex; justify-content: center; align-items: center; margin-left: 10px; margin-right: 15px; } .sb-notification-icon svg{ width: 22px; height: 22px; float: left; fill: currentColor; } .sb-notification-ctn[data-type="success"] .sb-notification-icon{ color: #59AB46; } .sb-notification-ctn[data-type="error"] .sb-notification-icon{ color: #D72C2C; } .sb-notification-ctn[data-type="message"] .sb-notification-icon{ color: #141B38; } .sb-notification-ctn span{ font-size: 14px; color: #141B38; font-weight:500; } /* Onboarding */ .sb-onboarding-tooltip { display: none; position: absolute; min-height: auto; width: 432px; max-width: 100%; padding: 0; border-radius: 2px; } #sb-onboarding-tooltip-multiple-2, #sb-onboarding-tooltip-multiple-3{ width: 528px; } #sb-onboarding-tooltip-single-2 { width: 402px; } .sb-onboarding-active .sb-onboarding-highlight .sbi-fb-btn.sbi-fb-btn-new, .sb-onboarding-active .sb-positioning-wrap.sb-onboarding-highlight, .sb-onboarding-active .sbi-fd-lst-bigctn .sbi-table-wrap.sb-onboarding-highlight, .sb-onboarding-active .sbi-fb-lgc-ctn.sb-onboarding-highlight, .sb-onboarding-active .sbi-fb-lgc-ctn .sbi-legacy-table-wrap.sb-onboarding-highlight{ position: relative; z-index: 100000; } .sb-onboarding-active .sbi-fd-legacy-feed-toggle { display: none; } .sbi-legacy-table-wrap.sb-onboarding-highlight { clear: both; } .sb-onboarding-tooltip-1 { top: 50px; left: 8px; } #sb-onboarding-tooltip-single-2 { bottom: -179px; top: auto; left: 68%; margin-left: -201px; } #sb-onboarding-tooltip-multiple-2, #sb-onboarding-tooltip-multiple-3{ top: -200px; left: 20%; } #sb-onboarding-tooltip-multiple-3 { top: -210px; } .sb-onboarding-tooltip .sbi-fb-wrapper { display: flex; justify-content: flex-end; } .sb-positioning-wrap { width: 432px; } .sb-onboarding-tooltip .sbi-fb-popup-cls { position:absolute; width: 12px; height: 12px; top: 12px; right: 12px; } .sb-onboarding-tooltip .sbi-fb-popup-cls svg { width: 12px; height: 12px; } .sb-onboarding-tooltip h3 { font-size: 16px; color: #141B38; line-height: 160%; font-weight: 600; margin: 0; } .sb-onboarding-step { font-style: normal; font-weight: normal; font-size: 12px; line-height: 160%; color: #434960; margin: 2px 0 20px; display: block; } .sbi-onboarding-next, .sbi-onboarding-previous{ color: #353A41; background: #F3F4F5; border: 1px solid #DCDDE1; margin-left: 10px; } .sb-onboarding-tooltip .sbi-fb-hd-btn { margin-right: 0; } .sb-onboarding-tooltip .sbi-fb-hd-btn i { margin: 0; } .sbi-onboarding-finish{ margin-left: 10px; padding: 0 32px; } .sb-onboarding-tooltip .sbi-fb-hd-btn[data-active="false"] { background-color: #e8e8eb; color: #8c8f99; } .sb-onboarding-tooltip .sbi-fb-hd-btn[data-active="false"]:hover { cursor: default; } .sb-step-counter-wrap span { font-style: normal; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; color: #141B38; } .sb-onboarding-tooltip .sb-pointer { position: absolute; left: 50px; top: -14px; } .sb-onboarding-tooltip .sb-pointer.sb-bottom-pointer { top: auto;; bottom: -14px; } #sb-onboarding-tooltip-single-2 .sb-pointer { left: 193px; } #sb-onboarding-tooltip-multiple-2:before, #sb-onboarding-tooltip-multiple-3:before{ bottom: -8px; } .sb-onboarding-top-row { padding: 20px 44px 0 24px; } .sb-onboarding-bottom-row { display: flex; flex-direction: row; justify-content: space-between; align-items: center; padding: 8px 16px 12px 24px; } /*Vue Color Picker*/ .sb-control-colorpicker-ctn .vc-sketch{ box-shadow: none!important; } .sb-control-colorpicker-popup{ box-shadow: 0px 0px 10px rgba(0,0,0,0.2); position: absolute; z-index: 99; top: 100%; background: #fff; right: 0px; } .sb-control-colorpicker-popup .sb-colorpicker-reset-btn{ width: calc(100% - 20px); margin-left: 10px; margin-bottom: 15px; } .sb-control-colorpicker-swatch{ width: 38px; height: 38px; position: absolute; right: 1px; top: 1px; background: #f7f7f7; } .sb-control-colorpicker-ctn .sb-control-input{ width: 100%; } @media (min-width: 768px) and (max-width: 1023px) { .sbi-csz-header-insider .sb-button-standard { padding: 10px 14px 10px 30px; } } @media (min-width: 1024px) and (max-width: 1200px) { .sbi-fb-wlcm-inf-3 { padding-left: 120px; } } @media (max-width: 767px) { .sbi-fd-lst-thtf th:nth-child(3), .sbi-fd-lst-thtf th:nth-child(4), .sbi-fd-lst-tbody tr td:nth-child(3), .sbi-fd-lst-tbody tr td:nth-child(4), .sbi-fd-lst-thtf tr td:nth-child(3), .sbi-fd-lst-thtf tr td:nth-child(4) { display: none; } .sbi-fd-lst-thtf th:last-child, .sbi-fd-lst-thtf tr td:last-child { padding-right: 15px; text-align: right; } .sbi-fd-lst-tbody tr td.sbi-fd-lst-actions .sb-flex-center{ justify-content: flex-end; padding-right: 8px; } .sbi-fb-full-wrapper { padding: 70px 20px 0 20px; } .sbi-fb-header { padding: 0px 20px; } .sbi-bld-ft-content { flex-wrap: wrap; } #sb-footer-banner .sbi-bld-ft-img { width: 100%; height: 140px; } #sb-footer-banner .sbi-bld-ft-img img { height: 100%; width: auto; } #sb-footer-banner .sbi-bld-ft-txt { justify-content: center; align-items: center; width: 100%; margin-right: 3%; padding: 20px; } .sbi-bld-ft-action { width: 100%; padding: 0 20px 20px; } .sbi-bld-footer > div { margin-bottom: 60px; } /* single feed page */ .sbi-csz-header-insider { flex-wrap: wrap; height: auto; width: 100%; } .sbi-fb-header.sbi-csz-header { height: 110px; } .sbi-csz-header.sbi-fb-header { padding-bottom: 6px; } .sbi-csz-header .sbi-csz-hd-actions { margin-top: 10px; } .sb-customizer-preview { display: none; } .sb-customizer-ctn .sb-customizer-sidebar { position: initial; margin-top: 110px; width: 100%; } .sb-notification-ctn { left: 20px; } .sbi-fb-header .sb-button-standard{ padding: 10px 10px 10px 31px; } .sbi-fb-embed-ctn.sb-fs-boss.sbi-fb-center-boss .sbi-fb-popup-inside { top: 35px; } .sbi-fb-embed-btns-ctn { grid-template-columns: 100%; } .sbi-fb-embed-btns-ctn .sbi-fb-embed-btn { margin-bottom: 10px; } .sbi-fb-embed-ctn.sb-fs-boss.sbi-fb-center-boss .sbi-fb-popup-inside .sbi-fb-embed-step-1-top { margin-bottom: 10px; } .sbi-fb-embed-ctn.sb-fs-boss.sbi-fb-center-boss .sbi-fb-popup-inside .sbi-fb-embed-input-ctn { flex-wrap: wrap; } .sbi-fb-embed-input-ctn input, .sbi-fb-embed-input-ctn input[type="text"] { width: 100%; border-right: 1px solid #D0D1D7!important; } .sbi-fb-embed-input-ctn .sbi-fb-hd-btn { width: 32%; max-width: 120px; margin-top: 10px !important; padding: 8px; } .sb-fs-boss.sbi-fb-center-boss { z-index: 100001 !important; } #sb-footer-banner .sbi-bld-ft-txt { flex-wrap: wrap; } #sbi-builder-app #sb-footer-banner h3, #sbi-builder-app #sb-footer-banner .sb-small-p { width: 100%; } #sbi-builder-app #sb-footer-banner h3 { margin-bottom: 10px; } .sbi-fb-srcslist-ctn { grid-template-columns: 100% } .sbi-fb-mr-fd-img { width: 100%; margin-right: 0; } .sbi-fb-mr-fd-img svg { max-width: 100%; } .sbi-fd-lst-tbody tr td:nth-child(2) { width: 50%; } .sbi-fb-wlcm-inf-1, .sbi-fb-wlcm-inf-2, .sbi-fb-wlcm-inf-3 { padding-left: 0; } .sbi-fb-wlcm-inf-3 .sbi-fb-inf-img, .sbi-fb-wlcm-inf-2 .sbi-fb-inf-img, .sbi-fb-wlcm-inf-1 .sbi-fb-inf-svg { display: none; } .sbi-fb-wlcm-inf-3 .sbi-fb-inf-cnt { justify-content: flex-start; } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-cnt { width: calc(100% - 53px); } .sbi-fb-wlcm-inf-2 .sbi-fb-inf-cnt, .sbi-fb-wlcm-inf-3 .sbi-fb-inf-cnt { width: 100%; } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-cnt .sbi-fb-inf-txt{ width: 80%; } .sbi-fb-wlcm-inf-2 .sbi-fb-inf-cnt { margin-bottom: 24px; } } @media (min-width: 768px) and (max-width: 1023px) { .sbi-fb-wlcm-inf-3 { padding-left: 7px; } .sbi-fb-wlcm-inf-2 { padding-left: 52px; } .sbi-fb-wlcm-inf-1 { padding-left: 85px; } .sbi-fb-wlcm-inf-1 .sbi-fb-inf-svg { display: none; } } /* Multiple Sources Sections */ #sbi-multiple-sources-ctn .sbi-fb-slctsrc-content{ padding: 25px 30px; border-bottom: 1px solid #E8E9EA; } .sbi-feedtype-section{ padding: 30px; border-bottom: 1px solid #E8E9EA; } .sbi-feedtype-sec-icon-heading{ display: flex; align-self: center; } .sbi-feedtype-icon-wrap svg{ width: 16px!important; height: 16px!important; float: left; fill: #0096CC; margin-right: 6px; } .sbi-feedtype-sec-icon-heading span{ color: #141B38; font-weight:600; font-size: 18px; } .sbi-feedtype-sec-icon-heading a{ font-size: 12px; display: inline-block; margin-top: 2px; margin-left: 6px; } .sbi-feedtype-sec-desc{ font-size: 12px; } #sbi-multiple-sources-ctn .sbi-fb-hd-btn svg{ fill: #141B38; } .sbi-addsource-type-btn{ display: flex; justify-content: center; align-self: center; padding: 12px 20px; color: #8C8F9A; cursor: pointer; font-size: 14px; font-weight: 600; } .sbi-addsource-type-btn svg{ margin-right: 12px; margin-top: 2px; fill: #8C8F9A; } .sbi-addsource-type-btn:hover, .sbi-addsource-type-btn:hover svg{ color: #434960; fill: #434960; } .sbi-feedtype-section .sbi-fd-lst-btn-delete{ height: 32px; width: 36px; position: absolute; right: 20px; top: 20px; z-index: 2; } .sbi-feedtype-icon-wrap { position: absolute; top: 0; left: 0; } .sbi-feedtype-sec-wrap { margin-left: 28px; } .sbi-feedtype-section .sbi-fd-lst-btn-delete{ border-color: #D8DADD; } .sbi-fb-type-el[data-checked="true"]{ border: 1px solid #D8D8D8 } .sbi-fb-type-el[data-checked="true"]:before{ content: ''!important; position: absolute!important; height: 100%!important; width: 100%!important; left: 0!important; top: 0!important; background: #f1f1f1!important; opacity: .35!important; cursor: default!important; } .sbi-fb-type-el[data-checked="true"]:after{ display: none!important; } .sbi-fb-type-el[data-checked="true"] .sbi-fb-type-el-info *{ color: #8C8F9A!important; } .sbi-fb-type-el-info .sb-control-elem-tltp, .sbi-fb-type-el-info .sb-control-elem-tltp-icon{ display: inline-block; color: inherit; fill: currentColor; margin: 0px; } .sbi-fb-feedtypes-pp-ctn .sbi-fb-type-el-info{ padding: 0 45px 20px!important; } .sbi-fb-feedtypes-pp-ctn .sbi-fb-types-list{ grid-template-columns: 24% 24% 24% 24%; } #sbi-builder-app .sbi-fb-feedtypes-pp-ctn .sbi-fb-types{ padding: 23px 30px 10px!important;; padding-bottom: 0px!important; } .sbi-fb-feedtypes-popup .sb-button-no-border { position: absolute; z-index: 99; top: 20px; left: 33px; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; cursor: pointer; } .sbi-fb-feedtypes-popup .sb-button-no-border svg { margin-right: 9px; } .sbi-fb-addsourtype-ctn{ margin-bottom: 30px; padding: 0px 30px!important; } .sbi-fb-addsourtype-ctn .sbi-fb-source-btn{ margin-top: 0px; } .sbi-fb-feedtypes-pp-ctn h4{ margin-bottom: 20px; } .sbi-fb-sourcelist-pp-ctn .sbi-fb-source-top{ padding: 22px 19px 0px; } .sbi-fb-sourcelist-pp-ctn .sbi-fb-sourcelist-pp{ float: left; width: 100%; box-sizing: border-box; padding: 0 20px; } .sbi-fb-sourcelist-pp-ctn .sbi-fb-addsourtype-ctn{ padding: 0px 20px!important; } .sbi-fb-sourcelist-pp-ctn .sbi-fb-srcs-desc{ margin-bottom: 20px; } .sbi-fb-sourcelist-pp-ctn .sbi-fb-source-pp-customizer .sbi-fb-srcslist-ctn{ grid-template-columns: 49% 49%; min-height: 80px; overflow: auto; } .sbi-selected-sources-ctn .sbi-fb-hd-btn{ display: inline-flex; margin-bottom: 7px; float: left; } .sbi-selected-source-item{ width: auto; height: 38px; border: 1px solid #D0D1D7; border-radius: 2px; display: inline-flex; align-items: center; margin-right: 10px; margin-bottom: 7px; box-sizing: border-box; float: left; } .sbi-selected-source-item-avatar, .sbi-selected-source-item-avatar img{ width: 36px; height: 36px; } .sbi-selected-source-item-avatar { border-right: 1px solid #F3F4F5; } .sbi-selected-source-item span{ font-weight:600; margin: 0px 10px; font-size: 13px; } .sbi-selected-source-item-icon{ margin-left: auto; width: 36px; height: 36px; display: flex; justify-content: center; align-items: center; cursor: pointer; } .sbi-selected-source-item-icon svg{ fill: #D72C2C; width: 14px; height: 14px; float: left; } #sbi-multiple-sources-ctn .sbi-feedtype-sec-desc{ margin: 4px 0 16px; } .sbi-hashtag-item{ display: inline-flex; font-weight: 400; height: 26px; font-size: 12px; align-items: center; padding: 0px 6px 1px 10px; border-radius: 50px; background: #f3f1f1; margin-right: 10px; margin-bottom: 10px; } .sbi-hashtag-item-delete{ width: 16px; height: 16px; background: #8C8F9A; color: #fff; margin-left: 5px; border-radius:50px; cursor: pointer; position: relative; } .sbi-hashtag-item-delete:before, .sbi-hashtag-item-delete:after{ content: ''; position: absolute; height: 2px; width: 8px; background: currentColor; left: 4px; top: 7px; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-hashtag-item-delete:after{ -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-hashtag-fetchby-chbx{ display: flex; margin-bottom: 15px; margin-top: 10px; } .sbi-hashtag-fetchby-chbx .sbi-fb-stp-src-type{ margin-left: 0px!important; margin-right: 20px!important; } /* Custom View Control With Image & info */ .sb-control-imginfo-elem{ background: #F9F9FA; border: 1px solid #E8E8EB; padding: 20px 30px; } .sb-control-imginfo-icon svg{ fill: none!important; } .sb-control-imginfo-icon{ display: flex; justify-content: center; align-self: center; } .sb-control-imginfo-text{ display: flex; flex-direction: column; padding-top: 20px; } .sb-control-imginfo-text [data-textalign="center"]{ justify-content: center; } .sb-control-imginfo-text strong{ font-size: 18px; margin-bottom: 20px; line-height: 1.3; } .sb-control-shoppbale-enbaled-ctn .sb-control-imginfo-text strong{ font-size: 14px; text-align: center; line-height: 1.4em; } .sb-control-imginfo-text span{ color: #434960; font-size: 14px; } .sb-shoppable-edit-btn{ position: absolute; right: 10px; top: 10px; cursor: pointer; z-index: 9; padding: 7px 13px 8px 35px; border: 2px solid rgba(255,255,255,.1); } .sb-shoppable-edit-btn-link svg{ width: 16px; height: 10px; top: 10px; fill: currentColor; } .sb-control-selectedpost-info{ display: flex; align-items: center; box-sizing: border-box; padding: 10px; border: 1px solid #D0D1D7; margin-bottom: 30px; margin-top: 10px; } .sb-control-selectedpost-info img{ width: 77px; height: 77px; } .sb-control-selectedpost-info span{ padding: 0 15px; color: #141B38; font-size: 13px; line-height: 1.6em; } .sb-control-selectedpost-input span{ color: #434960; font-size: 13px; margin-bottom: 5px; } .sb-control-selectedpost-btns{ display: grid; grid-template-columns: 48% 48%; grid-column-gap: 4%; margin-top: 10px; } .sb-control-selectedpost-btns button{ cursor: pointer; font-weight: 600; display: flex; justify-content: center; align-items: center; padding: 9px; } .sb-control-selectedpost-btns button svg{ margin-right: 10px; } /* Feed Type Customizer */ .sb-control-feedtype-item{ margin-bottom: 30px; padding-bottom: 20px; } .sb-control-feedtype-item:after{ content: ''; position: absolute; height: 1px; width: calc(100% + 40px); left: -20px; background: #DCDDE1; bottom: 0px; } .sb-control-feedtype-item:last-of-type:after{ display: none; } .sb-control-feedtype-list{ margin-top: 10px; } .sb-control-feedtype-list-item{ float: left; height: 30px; display: flex; justify-content: center; align-items: center; background: #F3F4F5; border-radius: 50px; padding: 0 14px; margin-right: 10px; margin-bottom: 10px; } .sb-control-feedtype-list-item-icon{ display: flex; justify-content: center; align-items: center; } .sb-control-feedtype-list-item svg{ width: 12px; margin-right: 4px; fill: #0096CC; } .sbi-fb-extppcustomizer-btns{ display: grid; grid-template-columns: 49% 49%; grid-column-gap: 1%; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-fb-feedtypes-popup{ padding: 22px 20px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-fb-source-top{ padding: 0px; padding-bottom: 22px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-fb-feedtypescustomizer-content{ background: #F9F9FA; border: 1px solid #E8E8EB; margin-bottom: 20px; border-radius: 4px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-feedtype-section{ box-shadow: unset; border-bottom: 1px solid #E8E8EB; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-feedtype-section:last-of-type{ border-bottom: 0px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-feedtype-sec-desc{ margin-bottom: 20px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-hashtag-fetchby .sbi-feedtype-sec-desc{ margin-bottom: 0px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-selected-source-item{ border: 1px solid #e1e1e1; } .sbi-fb-feedtypescustomizer-content .sbi-fb-hd-btn svg{ fill: #141B38; } .sbi-fb-feedtypescustomizer-content .sbi-feedtype-icon-wrap svg{ width: 20px!important; height: 20px!important; } .sbi-fb-feedtypescustomizer-content .sbi-feedtype-section{ padding: 24px; } /* Moderation Mode */ .sb-control-moderationmode-action-btns{ padding-top: 30px; } .sb-control-moderationmode-action-btns button{ margin-bottom: 20px; } .sbi-moderation-overlay-ctn{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; z-index: 8; cursor: pointer; } .sbi-moderation-toggle{ position: absolute; width: 66px; height: 22px; top: 10px; right: 10px; background: #FFFFFF; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); border-radius: 2px; padding: 2px; } .sbi-moderation-toggle-icon{ width: 33px; height: 22px; position: relative; float: left; border-radius: 2px; color: #8C8F9A; } .sbi-moderation-toggle[data-type="active"] .sbi-moderation-checkmark{ background: #59AB46; color: #fff!important; } .sbi-moderation-toggle[data-type="inactive"] .sbi-moderation-x{ background: #D72C2C; color: #fff!important; } .sbi_expand{ cursor: pointer; } .sbi-moderation-checkmark:before{ content: ''; position: absolute; width: 13px; height: 5px; left: 8px; top: 5px; border-bottom: 2px solid currentColor; border-left: 2px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-moderation-x:before, .sbi-moderation-x:after{ content: ''; position: absolute; width: 15px; height: 2px; left: 9px; top: 10px; background: currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-moderation-x:after{ -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sb-control-moderationmode-elements > .sb-control-switcher-ctn{ margin-bottom: 25px; } .sbi_header_text h3{ color: inherit; } .sbi-customizer-ms-modes .sbi_link, .sbi-customizer-ms-modes .sb_instagram_header{ display: none!important; } .sbi-moderation-pagination{ display: flex; margin-top: 20px; justify-content: flex-end; } .sbi-moderation-pagination-btn{ margin-left: 20px; } #sb_instagram .sbi_item:not(.sbi_transition) .sbi_photo, #sb_instagram.sbi_highlight #sbi_images, #sb_instagram.sbi_masonry #sbi_images, #sb_instagram #sbi_images .sbi_item{ -webkit-transition: unset!important; transition: unset!important; } #sb_instagram .sbi_item:not(.sbi_transition):hover .sbi_photo{ -webkit-transition: all .5s!important; transition: all .5s!important; } #sb_instagram .sbi_item .sbi_photo_shady{ position: absolute; left: 0; top: 0; height: 100%; width: 100%; z-index: 2; background-position: inherit; background-size: inherit; } /* FREE */ .sbi-fb-types-list-free{ display: block; grid-template-columns: unset; grid-column-gap: unset; margin-bottom: 31px; margin-top: 25px; } .sbi-fb-types-list-free .sbi-fb-type-el > div{ height: 100%; } .sbi-fb-types-list-free .sbi-fb-type-el{ width: 420px; max-width: 100%; height: 165px; flex-direction: row; align-items: center; } .sbi-fb-types-list-free .sbi-fb-type-el .sbi-fb-type-el-info{ text-align: left; align-items: flex-start; justify-content: center; } .sbi-fb-types-list-free .sbi-fb-type-el .sbi-fb-type-el-info > *{ padding: 0 20px; } .sbi-fb-types-list-pro{ display: grid; grid-template-columns: 24.5% 24.5% 24.5% 24.5%; grid-column-gap: 0.5%; margin-top: 10px; } .sbi-fb-type-el-pro{ display: flex; flex-direction: row; align-items: center; padding: 12px 20px 12px 12px; background: #F9F9FA; border: 1px solid #D0D1D7; box-sizing: border-box; border-radius: 2px; color: #141B38; font-weight: 600; font-size: 14px; margin-bottom: 10px; cursor: pointer; } .sbi-fb-type-el-pro:hover{ background: #E2F5FF; border: 1px solid #E2F5FF; } .sbi-fb-type-el-pro-img svg{ float: left; } .sbi-fb-type-el-pro-img{ margin-right: 20px; } /*Lite Top Banner Dismiss*/ .sbi-builder-app-lite-dismiss .sbi-header-notice{ position: fixed!important; top: 32px; width: 100%; z-index: 2; left: 0; } .sbi-builder-app-lite-dismiss .sbi-fb-header{ top: 64px; } .sbi-builder-app-lite-dismiss .sb-customizer-sidebar{ top: 128px; } .sbi-builder-app-lite-dismiss .sb-customizer-preview{ margin-top: 100px; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-addsource-type-btn{ color: #0068A0; } .sbi-fb-feedtypescustomizer-pp-ctn .sbi-addsource-type-btn svg{ fill: #0068A0; } .sb-control-label-pro-toggle{ display: inline-block; background: #b9b9b9; color: #fff; border-radius: 3px; padding: 1px 8px; text-transform: uppercase; font-size: 11px; margin-left: 2px; } /* Onboarding Wizard */ .sb-onboarding-wizard-ctn { width: calc(100% + 160px); position: absolute; background: #E6E6EB; padding: 0 20px; box-sizing: border-box; border-top: 2px solid #434960; min-height: 100vh; left: -160px; top: -34px; z-index: 9999999; padding-top: 100px; padding-bottom: 100px; margin-top: 0px; } .sb-onboarding-wizard-ctn[data-step="0"]{ z-index: 1; } .instagram-feed_page_sbi-setup .sbi-fb-source-ctn, .instagram-feed_page_sbi-setup .sb-dialog-ctn { z-index: 999999999999999999999; } .folded .sb-onboarding-wizard-ctn { width: calc(100% + 36px); left: -36px; } .sb-onboarding-wizard-ctn[data-step="0"]{ position: relative; width: 100%!important; left: 0!important; top: 0!important; padding-top:0px!important; border-color: transparent!important; margin-top: 63px; } .sb-onboarding-wizard-wrapper { width: 850px; max-width: 100%; margin: auto; margin-top: 50px; } .sb-onboarding-wizard-wrapper[data-step="0"]{ width: 1200px; margin-top: 100px; } .sb-onboarding-wizard-wrapper>div { width: 100%; box-sizing: border-box; float: left; position: relative; } .sb-onboarding-wizard-top { display: flex; justify-content: center; align-items: center; } .sb-onboarding-wizard-logo-ctn { display: flex; justify-content: center; align-items: center; width: 68px; height: 68px; position: relative; margin-right: 35px; margin-left: -35px; } .sb-onboarding-wizard-logo1-ctn { display: flex; justify-content: center; align-items: center; width: 46px; height: 68px; position: relative; margin-right: 15px; margin-left: -15px; } .sb-onboarding-wizard-logo-balloon1{ width: 100%; float: left; } .sb-onboarding-wizard-logo-ctn:after { content: ''; position: absolute; width: 100%; height: 100%; background: #fff; border-radius: 10px; box-shadow: 0px 1.4945039749145508px 2.0379600524902344px 0px #00000012, 0px 4.1321120262146px 5.634698390960693px 0px #0000000C, 0px 9.94853401184082px 13.566183090209961px 0px #00000009, 0px 33px 45px 0px #00000006; -webkit-transform: rotate(-10deg); transform: rotate(-10deg); } .sb-onboarding-wizard-logo-ctn img { z-index: 2; } .sb-onboarding-wizard-logo-balloon { position: absolute; right: -15px; bottom: -13px; } .sb-onboarding-wizard-plugin-name h3 { font-weight: 600 !important; color: #141B38; font-size: 32px !important; line-height: 1.1em !important; } .sb-onboarding-wizard-plugin-name span { font-weight: 600; color: #141B38; font-size: 20px; opacity: .6; margin-top: 6px; float: left; } .sb-onboarding-wizard-steps { margin-top: 50px; height: 20px; display: flex; align-items: center; justify-content: space-between; } .sb-onboarding-wizard-steps:before { content: ''; position: absolute; width: 100%; height: 2px; background: #CED0D9; margin-top: -1px; } .sb-onboarding-wizard-step-icon { width: 20px; height: 20px; position: relative; background: #fff; border: 4px solid #CED0D9; border-radius: 25px; box-sizing: border-box; } .sb-onboarding-wizard-step-icon:before { content: ''; position: absolute; width: calc(100% + 6px); height: calc(100% + 6px); border: 3px solid #E6E6EB; left: -6px; top: -6px; border-radius: inherit; z-index: 1; } .sb-onboarding-wizard-step-icon[data-active="true"] { border-color: #0096CC; } .sb-onboarding-wizard-step-icon[data-active="done"] { background: #2C324C; border-color: #2C324C; } .sb-onboarding-wizard-step-icon[data-active="done"]:after { content: ''; position: absolute; height: 3px; width: 8px; color: #fff; border-left: 2px solid currentColor; border-bottom: 2px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); top: 2px; left: 1px; } .sb-onboarding-wizard-step-ctn { width: 100%; float: left; margin-top: 30px; } .sb-onboarding-wizard-step-wrapper { background: #fff; border-radius: 5px; padding-bottom: 20px; box-shadow: 0px 4px 5px 0px #0000000D, 0px 1px 2px 0px #0000000D; } /* .sb-onboarding-wizard-step-welcome { display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; padding: 100px 20%; } */ .sb-onboarding-wizard-step-welcome { display: grid; grid-template-columns: 55% 45%; padding-bottom: 0px; } .sb-onboarding-wizard-welcome-text{ padding: 0px 10%; display: flex; flex-direction: column; justify-content: center; } .sb-onboarding-wizard-welcome-banner { background-color:#0068A0; border-top-right-radius: 5px; border-bottom-right-radius: 5px; } .sb-onboarding-wizard-welcome-banner img{ width: 100%; height: auto; float: left; border-radius: inherit; } .sb-onboarding-wizard-welcome-btns { display: flex; column-gap: 15px; } .sb-onboarding-wizard-step-welcome h3 { font-size: 24px !important; font-weight: 600 !important; line-height: 29px !important; margin-top: 0px !important; margin-bottom: 5px !important; } .sb-onboarding-wizard-step-welcome p { font-size: 14px; font-weight: 400; line-height: 22px; margin-bottom: 45px; color: #696D80; } .sb-onboarding-wizard-step-welcome button { padding: 16px 25px; font-weight: 600; border-radius: 4px; flex-grow: 1; position: relative; } .sb-onboarding-wizard-step-welcome button.sb-btn-wizard-next:before, .sb-onboarding-wizard-upgrade-btns a.sb-btn-wizard-next:before{ left: unset; top: 21px; right: 40px; } .sb-onboarding-wizard-step-top { display: flex; flex-direction: column; padding: 20px 20px; border-bottom: 1px solid #E6E6EB; } .sb-onboarding-wizard-step-top[data-large="true"] { padding: 30px 20px; } .sb-onboarding-wizard-step-top strong { font-size: 12px; font-weight: 700; line-height: 19px; letter-spacing: 0.05em; color: #696D80; } .sb-onboarding-wizard-step-top h4 { font-size: 18px !important; font-weight: 600 !important; line-height: 25px !important; color: #000; } .sb-onboarding-wizard-step-top[data-large="true"] h4 { font-size: 20px !important; } .sb-onboarding-wizard-step-top span { font-size: 14px; font-weight: 400; line-height: 22px; color: #696D80; } .sb-onboarding-wizard-step-pag-btns { display: flex; justify-content: flex-end; margin-top: 30px; } .sb-onboarding-wizard-step-pag-btns button { padding: 10px 20px 10px 33px !important; margin-left: 20px !important; border-radius: 5px; position: relative; } .sb-btn-wizard-next:before, .sb-btn-wizard-back:before { content: ''; position: absolute; width: 5px; height: 5px; border-left: 2px solid currentColor; border-bottom: 2px solid currentColor; left: 15px; top: 15px; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sb-btn-wizard-next:before { left: 15px; top: 15px; -webkit-transform: rotate(230deg); transform: rotate(230deg); } .sb-onboarding-wizard-ctn button { -webkit-transition: unset !important; transition: unset !important; } .sb-onboarding-wizard-elements-list>div { padding: 25px; } .sb-onboarding-wizard-elements-list>div:nth-child(odd), .sb-onboarding-wizard-success-list>div:nth-child(odd) { background: #F9F9FA; } .sb-onboarding-wizard-elem-info { display: inline-flex; width: calc(100% - 50px); float: left; align-content: flex-start; } .sb-onboarding-wizard-elem-icon { width: 28px; height: 28px; margin-right: 20px; display: flex; justify-content: center; align-items: center; } .sb-onboarding-wizard-elem-icon img{ width: 28px; height: 28px; float: left; } .sb-onboarding-wizard-elem-text { display: flex; flex-direction: column; } .sb-onboarding-wizard-elem-text strong { font-size: 16px; font-weight: 600; line-height: 26px; } .sb-onboarding-wizard-elem-text span { font-size: 14px; font-weight: 400; line-height: 22px; color: #434960; } .sb-onboarding-wizard-elem-toggle { width: 50px; float: right; } .sb-onboarding-wizard-elem-toggle>div { width: 36px; height: 16px; padding: 2px; border-radius: 31px; background-color: #9295A6; position: relative; cursor: pointer; } .sb-onboarding-wizard-elem-toggle>div[data-color="green"][data-active="true"] { background-color: #59AB46; } .sb-onboarding-wizard-elem-toggle>div[data-uncheck="true"] { opacity: .5; cursor: auto; } .sb-onboarding-wizard-elem-toggle>div:before { content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50px; top: 2px; left: 3px; background-color: #fff; box-shadow: 0px 1px 2px 0px #00000040; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sb-onboarding-wizard-elem-toggle>div[data-active="true"]:before { left: 22px; } .sb-onboarding-wizard-elem-toggle>div[data-color="blue"][data-active="true"]{ background-color: #0096CC; } .sb-onboarding-wizard-elements-list-hd { padding: 20px !important; padding-top: 50px !important; background-color: #fff !important; border-bottom: 1px solid #E6E6EB !important; font-size: 18px !important; font-weight: 600 !important; line-height: 25px !important; } .sb-onboarding-wizard-step-configuref { padding-bottom: 30px; } .sb-onboarding-wizard-success-list{ overflow: hidden; } .sb-onboarding-wizard-step-success{ padding-bottom: 0px; } .sb-onboarding-wizard-succes-elem { padding: 0px 22px; display: flex; align-items: center; column-gap: 10px; visibility: hidden; opacity: 0; height: 0px; transform: translateX(-20px); transition: all .3s ease-in-out; } .sb-onboarding-wizard-success-list[data-done="true"] .sb-onboarding-wizard-succes-elem { height: 54px; visibility: visible; opacity: 1; transform: translateX(0px); } .sb-onboarding-wizard-success-list[data-done="true"] .sb-onboarding-wizard-succes-elem:last-of-type { margin-bottom: 20px; } .sb-onboarding-wizard-succes-icon { width: 20px; height: 20px; color: #468737; } .sb-onboarding-wizard-succes-icon svg path { stroke: currentColor; } .sb-onboarding-wizard-succes-text { font-size: 16px; font-weight: 400; line-height: 26px; color: #2C324C; } .sb-onboarding-wizard-upgrader { margin-top: 30px; /* background: #F9F9FA; */ padding: 30px 10%; box-shadow: 0px 4px 50px 0px #0000000D, 0px 1px 2px 0px #0000000D; border-radius: 5px; } .sb-onboarding-wizard-features-ctn, .sb-onboarding-wizard-license-ctn { background: #fff; border: 1px solid #E6E6EB; box-shadow: 0px 4px 5px 0px #0000000D, 0px 1px 2px 0px #0000000D; margin-bottom: 20px; border-radius: 5px; } .sb-onboarding-wizard-upgrader-features { background: #F9F9FA; display: flex; justify-content: center; align-items: center; padding: 15px 40px; column-gap: 8px; border-top-right-radius: 8px; border-top-left-radius: 8px; } .sb-onboarding-wizard-upgrader-feature-el { display: inline-flex; font-size: 13px; font-weight: 600; line-height: 21px; column-gap: 10px; justify-content: center; align-items: center; padding: 4px 8px; background: #FFFFFF; box-shadow: 0px 4px 10px 0px #0000000D, 0px 1px 2px 0px #0000000D; border-radius: 6px; margin: 3px 0px; } .sb-onboarding-wizard-upgrader-feature-el svg { float: left; } .sb-onboarding-wizard-upgrader-action-ctn { display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 40px 20px; } .sb-onboarding-wizard-upgrader-action-ctn h4 { font-size: 18px !important; font-weight: 600 !important; line-height: 25px !important; } .sb-onboarding-wizard-upgrader-action-ctn p { font-size: 15px; font-weight: 400; line-height: 21px; color: #696D80; padding: 0 20%; margin-bottom: 22px; text-align: center; } .sb-onboarding-wizard-upgrader-action-ctn a { font-size: 16px; font-weight: 600; line-height: 26px; text-align: left; padding: 10px 35px; border: 0px; border-radius: 4px; } .sb-onboarding-wizard-upgrader-bonus { display: flex; justify-content: center; align-items: center; background: #FFEFCC; border-bottom-right-radius: 8px; border-bottom-left-radius: 8px; font-size: 13px; font-weight: 400; line-height: 21px; padding: 8px 10px; column-gap: 5px; } .sb-onboarding-wizard-license-ctn { display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 40px 60px; } .sb-onboarding-wizard-license-ctn strong { font-size: 20px; font-weight: 600; line-height: 25px; text-align: center; color: #000; } .sb-onboarding-wizard-license-ctn p { font-size: 14px; font-weight: 400; line-height: 21px; text-align: center; color: #696D80; margin-top: 5px; margin-bottom: 22px; } .sb-onboarding-wizard-license-inp-ctn { display: flex; width: 100%; padding: 0 5%; align-items: center; justify-content: center; box-sizing: border-box; column-gap: 12px; } .sb-onboarding-wizard-license-inp-ctn input { flex: 1; padding: 5px 10px!important; border: 1px solid #E6E6EB } .sb-onboarding-wizard-license-inp-ctn button { height: 40px; font-size: 14px; font-weight: 600; line-height: 22px; } .sb-onboarding-wizard-finish-ctn { display: flex; justify-content: center; align-items: center; } .sb-onboarding-wizard-finish-ctn button { font-weight: 600; font-size: 12px; color: #141B38 !important; padding: 13px 23px; line-height: 1em; } .sb-onboarding-wizard-finish-ctn button svg{ margin-left: 10px; float: left; margin-top: 3px; } .sb-onboarding-wizard-sources-list{ display: grid; grid-template-columns: 32.66% 32.66% 32.66%; grid-column-gap: 1%; margin-bottom: 10px; padding: 10px 20px; } .sb-onboarding-wizard-sources-list > div { display: flex; height: 52px; position: relative; border-radius: 3px; margin-bottom: 10px; } .sb-onboarding-wizard-source-newitem{ justify-content: center; align-items: center; background: #EBF5FF; border: 1px solid #EBF5FF; color: #0096CC; cursor: pointer; } .sb-onboarding-wizard-source-newitem span{ color: inherit!important; margin-left: 10px !important; } .sb-onboarding-wizard-source-item { align-items: center; box-sizing: border-box; padding: 0 10px; border: 1px solid #CED0D9; padding-bottom: 2px; } .sb-onboarding-wizard-source-item strong{ color: #000; } .sb-onboarding-wizard-source-item-avatar{ position: relative; width: 32px; height: 32px; border-radius: 50px; margin-right: 12px; } .sb-onboarding-wizard-source-item-avatar img{ width: inherit; height: inherit; border-radius: 50px; float: left; } .sb-onboarding-wizard-source-item-avatar svg{ position: absolute; right: -5px; bottom: -3px; } .sb-onboarding-wizard-source-item-delete{ display: flex; width: 20px; height: 20px; justify-content: center; align-items: center; cursor: pointer; margin-left: auto; } .sb-onboarding-wizard-source-item-delete svg{ float: left; } .sb-onboarding-wizard-succes-name{ text-transform: capitalize; } .sb-onboarding-wizard-upgrade-ctn{ display: grid; grid-template-columns: 54% 46%; background-color: #0068A0; box-shadow: 0px 4px 5px 0px #0000000D, 0px 1px 2px 0px #0000000D; margin-top: 20px; margin-bottom: 20px; border-radius: 5px; } .sb-onboarding-wizard-upgrade-banner img{ width: 100%; float: left; border-top-right-radius: 5px; border-bottom-right-radius: 5px; } .sb-onboarding-wizard-upgrade-text{ padding: 0px 10%; display: flex; flex-direction: column; justify-content: center; } .sb-onboarding-wizard-upgrade-text h3{ color: #fff; } .sb-onboarding-wizard-upgrade-text p { color: #fff; margin: 25px 0px; } .sb-onboarding-wizard-upgrade-btns a, .sb-onboarding-wizard-upgrade-btns a:hover{ color: #0068A0; background: #fff; padding: 16px 25px; position: relative; } .sb-onboarding-wizard-upgrade-off{ padding: 12px 20px; display: grid; grid-template-columns: 50px calc(100% - 50px); background: #FFDF99; margin-top: 18px; border-radius: 4px; } .sb-onboarding-wizard-upgrade-off div{ display: flex; width: 35px; height: 35px; justify-content: center; align-items: center; } .sb-onboarding-wizard-upgrade-off div svg{ float: left; } .sb-onboarding-wizard-upgrade-off span{ color:#331F00; } .sb-onboarding-wizard-close{ top: 0px; position: fixed; display: flex; justify-content: center; align-items: center; width: 120px; height: 40px; right: 100px; background-color: #434960; color: #fff; font-size: 14px; font-weight: 600; column-gap: 10px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; cursor: pointer; z-index: 99; } .instagram-feed_page_sbi-setup .sbi-header-notice{ display: none; } .instagram-feed_page_sbi-setup .sbi-stck-wdg { z-index: 99999999999; } .sb-btn-wizard-next:before, .sb-btn-wizard-install:before{ left: unset !important; right: 16px !important; } button.sb-btn-wizard-install, div:not(.sb-onboarding-wizard-welcome-btns) > button.sb-btn-wizard-next{ padding: 10px 33px 10px 20px !important; } .sb-onboarding-wizard-step-wrapper.sb-onboarding-wizard-step-installp{ padding-bottom: 0px; } .sb-onboarding-wizard-elem:last-of-type{ border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; } .sb-onboarding-wizard-license-error{ color: #D72C2C; display: flex; margin-top: 20px; font-weight: 500; } .sb-onboarding-wizard-license-error a{ text-decoration: underline; } .sb-onboarding-wizard-license-inp-ctn button svg{ fill: currentColor!important; margin-right: 10px; } .sb-onboarding-wizard-license-inp-ctn button svg path{ fill: currentColor !important; } @media (min-width: 760px) and (max-width: 960px) { .sb-onboarding-wizard-step-welcome { grid-template-columns: 70% 30%; } .sb-onboarding-wizard-welcome-text{ padding: 100px 10%; } .sb-onboarding-wizard-welcome-banner{ justify-content: center; display: flex; align-items: center; } } @media all and (max-width: 760px) { .sb-onboarding-wizard-step-welcome { display: flex; flex-direction: column-reverse; margin-bottom: 20px; } .sb-onboarding-wizard-welcome-text{ padding: 100px 10%; } } @media all and (max-width: 960px) { .sb-onboarding-wizard-ctn{ width: 100%; left: 0px; top: 0; } .sb-onboarding-wizard-sources-list{ grid-template-columns: 49% 49%; } } admin/builder/assets/css/tooltipster.css000064400000030317150515074570014473 0ustar00/* This is the core CSS of Tooltipster */ /* GENERAL STRUCTURE RULES (do not edit this section) */ .tooltipster-base { /* this ensures that a constrained height set by functionPosition, if greater that the natural height of the tooltip, will be enforced in browsers that support display:flex */ display: flex; pointer-events: none; /* this may be overriden in JS for fixed position origins */ position: absolute; } .tooltipster-box { /* see .tooltipster-base. flex-shrink 1 is only necessary for IE10- and flex-basis auto for IE11- (at least) */ flex: 1 1 auto; } .tooltipster-content { /* prevents an overflow if the user adds padding to the div */ box-sizing: border-box; /* these make sure we'll be able to detect any overflow */ max-height: 100%; max-width: 100%; overflow: auto; } .tooltipster-ruler { /* these let us test the size of the tooltip without overflowing the window */ bottom: 0; left: 0; overflow: hidden; position: fixed; right: 0; top: 0; visibility: hidden; } /* ANIMATIONS */ /* Open/close animations */ /* fade */ .tooltipster-fade { opacity: 0; -webkit-transition-property: opacity; -moz-transition-property: opacity; -o-transition-property: opacity; -ms-transition-property: opacity; transition-property: opacity; } .tooltipster-fade.tooltipster-show { opacity: 1; } /* grow */ .tooltipster-grow { -webkit-transform: scale(0,0); -moz-transform: scale(0,0); -o-transform: scale(0,0); -ms-transform: scale(0,0); transform: scale(0,0); -webkit-transition-property: -webkit-transform; -moz-transition-property: -moz-transform; -o-transition-property: -o-transform; -ms-transition-property: -ms-transform; transition-property: transform; -webkit-backface-visibility: hidden; } .tooltipster-grow.tooltipster-show { -webkit-transform: scale(1,1); -moz-transform: scale(1,1); -o-transform: scale(1,1); -ms-transform: scale(1,1); transform: scale(1,1); -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); } /* swing */ .tooltipster-swing { opacity: 0; -webkit-transform: rotateZ(4deg); -moz-transform: rotateZ(4deg); -o-transform: rotateZ(4deg); -ms-transform: rotateZ(4deg); transform: rotateZ(4deg); -webkit-transition-property: -webkit-transform, opacity; -moz-transition-property: -moz-transform; -o-transition-property: -o-transform; -ms-transition-property: -ms-transform; transition-property: transform; } .tooltipster-swing.tooltipster-show { opacity: 1; -webkit-transform: rotateZ(0deg); -moz-transform: rotateZ(0deg); -o-transform: rotateZ(0deg); -ms-transform: rotateZ(0deg); transform: rotateZ(0deg); -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 1); -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); -moz-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); -ms-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); -o-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); } /* fall */ .tooltipster-fall { -webkit-transition-property: top; -moz-transition-property: top; -o-transition-property: top; -ms-transition-property: top; transition-property: top; -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); } .tooltipster-fall.tooltipster-initial { top: 0 !important; } .tooltipster-fall.tooltipster-show { } .tooltipster-fall.tooltipster-dying { -webkit-transition-property: all; -moz-transition-property: all; -o-transition-property: all; -ms-transition-property: all; transition-property: all; top: 0 !important; opacity: 0; } /* slide */ .tooltipster-slide { -webkit-transition-property: left; -moz-transition-property: left; -o-transition-property: left; -ms-transition-property: left; transition-property: left; -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); } .tooltipster-slide.tooltipster-initial { left: -40px !important; } .tooltipster-slide.tooltipster-show { } .tooltipster-slide.tooltipster-dying { -webkit-transition-property: all; -moz-transition-property: all; -o-transition-property: all; -ms-transition-property: all; transition-property: all; left: 0 !important; opacity: 0; } /* Update animations */ /* We use animations rather than transitions here because transition durations may be specified in the style tag due to animationDuration, and we try to avoid collisions and the use of !important */ /* fade */ @keyframes tooltipster-fading { 0% { opacity: 0; } 100% { opacity: 1; } } .tooltipster-update-fade { animation: tooltipster-fading 400ms; } /* rotate */ @keyframes tooltipster-rotating { 25% { transform: rotate(-2deg); } 75% { transform: rotate(2deg); } 100% { transform: rotate(0); } } .tooltipster-update-rotate { animation: tooltipster-rotating 600ms; } /* scale */ @keyframes tooltipster-scaling { 50% { transform: scale(1.1); } 100% { transform: scale(1); } } .tooltipster-update-scale { animation: tooltipster-scaling 600ms; } /** * DEFAULT STYLE OF THE SIDETIP PLUGIN * * All styles are "namespaced" with .tooltipster-sidetip to prevent * conflicts between plugins. */ /* .tooltipster-box */ .tooltipster-sidetip .tooltipster-box { background: #565656; border: 2px solid black; border-radius: 4px; } .tooltipster-sidetip.tooltipster-left .tooltipster-box { margin-right: 8px; } .tooltipster-sidetip.tooltipster-right .tooltipster-box { margin-left: 8px; } .tooltipster-sidetip.tooltipster-top .tooltipster-box { margin-bottom: 8px; } /* .tooltipster-content */ .tooltipster-sidetip .tooltipster-content { color: white; line-height: 18px; padding: 6px 14px; } /* .tooltipster-arrow : will keep only the zone of .tooltipster-arrow-uncropped that corresponds to the arrow we want to display */ .tooltipster-sidetip .tooltipster-arrow { overflow: hidden; position: absolute; } .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow { height: 10px; /* half the width, for centering */ margin-left: -10px; top: 0; width: 20px; } .tooltipster-sidetip.tooltipster-left .tooltipster-arrow { height: 20px; margin-top: -10px; right: 0; /* top 0 to keep the arrow from overflowing .tooltipster-base when it has not been positioned yet */ top: 0; width: 10px; } .tooltipster-sidetip.tooltipster-right .tooltipster-arrow { height: 20px; margin-top: -10px; left: 0; /* same as .tooltipster-left .tooltipster-arrow */ top: 0; width: 10px; } .tooltipster-sidetip.tooltipster-top .tooltipster-arrow { bottom: 0; height: 10px; margin-left: -10px; width: 20px; } /* common rules between .tooltipster-arrow-background and .tooltipster-arrow-border */ .tooltipster-sidetip .tooltipster-arrow-background, .tooltipster-sidetip .tooltipster-arrow-border { height: 0; position: absolute; width: 0; } /* .tooltipster-arrow-background */ .tooltipster-sidetip .tooltipster-arrow-background { border: 10px solid transparent; } .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background { border-bottom-color: #565656; left: 0; top: 3px; } .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background { border-left-color: #565656; left: -3px; top: 0; } .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background { border-right-color: #565656; left: 3px; top: 0; } .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background { border-top-color: #565656; left: 0; top: -3px; } /* .tooltipster-arrow-border */ .tooltipster-sidetip .tooltipster-arrow-border { border: 10px solid transparent; left: 0; top: 0; } .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border { border-bottom-color: black; } .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border { border-left-color: black; } .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border { border-right-color: black; } .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border { border-top-color: black; } /* tooltipster-arrow-uncropped */ .tooltipster-sidetip .tooltipster-arrow-uncropped { position: relative; } .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped { top: -10px; } .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped { left: -10px; } @media (min-width: 960px) { body .sbi-tooltip-wizard.tooltipster-sidetip { left: 50px !important; top: 74px !important; } } .wp-editor .sbi-tooltip-wizard{ -webkit-transform: translateY(63px) translateX(17px); transform: translateY(63px) translateX(17px); } .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box{ background: #fff!important; border: 1px solid #eee!important; border-radius: 2px!important; box-shadow: 0px 1px 18px rgba(0,0,0,0.2)!important; } .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-content{ color: #434960!important; line-height: 18px; padding: 6px 20px!important; position: relative; } .sbi-tooltip-wizard .sbi-tooltip-wizard-head { color: #141B38; font-size: 15px; margin-bottom: 8px; width: 100%; float: left; display: block } .sbi-tooltip-wizard .sbi-tooltip-wizard-txt{ margin-bottom: 15px; } .sbi-tooltip-wizard .sbi-tooltip-wizard-actions button{ background: #F3F4F5!important; cursor: pointer!important; border: 1px solid #DCDDE1!important; padding: 5px 20px!important; } .sbi-tooltip-wizard .sbi-tooltip-wizard-actions{ margin-bottom: 10px; } .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:before, .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:after { content: ''; position: absolute; width: 20px; height: 20px; left: 20%; top: -8px; background: #fff; box-shadow: 0px 1px 18px rgba(0,0,0,0.2); z-index: 3; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:after { background: #fff; z-index: 999; top: 2px; margin-left: -10px; width: 40px; box-shadow: unset; -webkit-transform: rotate(0deg); transform: rotate(0deg); } .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-arrow{ display: none; } #sbi-gutenberg-tooltip-content{ display: none; } .sbi-tlp-wizard-cls{ position: absolute; width: 20px; height: 20px; right: 14px; top: 14px; cursor: pointer; } .sbi-tlp-wizard-cls:before, .sbi-tlp-wizard-cls:after{ content: ''; position: absolute; width: 16px; height: 2px; background: #141B38; left: 3px; top: 7px; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-tlp-wizard-cls:after{ -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-tooltip-wizard.tooltipster-sidetip #sbi-gutenberg-tooltip-content{ display: block; } .sbi-tooltip-wizard.tooltipster-sidetip { margin-top: 40px; margin-left: 74px; } .is-fullscreen-mode .sbi-tooltip-wizard.tooltipster-sidetip { margin-top: 10px; margin-left: -28px; } @media (max-width: 960px) { .sbi-tooltip-wizard.tooltipster-sidetip { margin-left: 0; } } @media (max-width: 782px) { .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:before, .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:after { left: 30px; } } @media (max-width: 599px) { .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:before, .sbi-tooltip-wizard.tooltipster-sidetip .tooltipster-box:after { left: 15px; } }admin/builder/assets/css/global.css000064400000205731150515074570013347 0ustar00/* Global CSS styles Theses styles can be used for different screens & In different SmashBalloon Plugins * Transitions * Default, Hover & Focus Colors & Backgrounds * Social Colors * Buttons * Full Screen Boss * Add Source Popup * Confirm Dialog * Full Screen Loader * Tooltip */ #sbi-settings{ visibility: hidden; opacity: 0; } #sbi-settings[data-app-loaded="true"]{ visibility: visible; opacity: 1; } #sbi-builder-app { -webkit-font-smoothing: antialiased; } /* Transitions */ .sb-tr-1{ -webkit-transition: all .1s ease-in-out; transition: all .1s ease-in-out; } .sb-tr-2{ -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sb-tr-3{ -webkit-transition: all .3s ease-in-out; transition: all .3s ease-in-out; } .sb-tr-4{ -webkit-transition: all .4s ease-in-out; transition: all .4s ease-in-out; } .sb-tr-5{ -webkit-transition: all .5s ease-in-out; transition: all .5s ease-in-out; } .sb-tr-6{ -webkit-transition: all .6s ease-in-out; transition: all .6s ease-in-out; } .sb-tr-7{ -webkit-transition: all .7s ease-in-out; transition: all .7s ease-in-out; } .sb-tr-8{ -webkit-transition: all .8s ease-in-out; transition: all .8s ease-in-out; } .sb-tr-9{ -webkit-transition: all .9s ease-in-out; transition: all .9s ease-in-out; } .sb-tr-10{ -webkit-transition: all 1s ease-in-out; transition: all 1s ease-in-out; } /* * Default, Hover & Focus Colors & Backgrounds */ .sb-small-p, .sb-standard-p{ font-style: normal; font-weight: normal; font-size: 14px; line-height: 160%; color: #8C8F9A; margin: 0; } .sb-standard-p{ font-size: 16px; color: #141B38; } #sbi-settings h3 { font-style: normal; font-weight: 600; font-size: 24px; line-height: 120%; margin: 0 0 4px 0; letter-spacing: 0; } .sb-caption { font-style: normal; font-weight: normal; font-size: 13px; line-height: 150%; color: #141B38; } .sb-caption.sb-caption-lighter { color: #5F6368; } .sb-small-text { font-size: 12px; } .sb-bold { font-weight: 600; } .sb-dark-text { color: #141B38; } .sb-small { font-style: normal; font-weight: bold; font-size: 10px; line-height: 160%; letter-spacing: 0.08em; text-transform: uppercase; color: #141B38; } .sb-button-no-border { border-radius: 0 !important; border: none !important; } .sb-icon-small svg { height: 10px; } .sb-dark-hover:hover svg, .sb-dark-hover:hover path { fill: #141B38; } /*orange*/ .sb-btn-orange{ background: #FE544F!important; color: #fff!important; } .sb-btn-orange:hover{ background: #EC352F!important; border-color: #EC352F!important; color: #fff!important; } .sb-btn-orange:focus, .sb-btn-orange:active{ background: #BC120E!important; border-color: #BC120E!important; color: #fff!important; } /*red*/ .sb-btn-red{ background: #D72C2C!important; color: #fff!important; } .sb-btn-red:hover{ background: #DF5757!important; color: #fff!important; } .sb-btn-red:focus, .sb-btn-red:active{ background: #841919!important; color: #fff!important; } /*red*/ .sb-btn-blue{ background: #0068A0!important; color: #fff!important; } .sb-btn-blue:hover{ background: #0096CC!important; border-color: #0096CC!important; color: #fff!important; } .sb-btn-blue:focus, .sb-btn-blue:active{ background: #004D77!important; border-color: #004D77!important; color: #fff!important; } /*grey*/ .sb-btn-grey{ background: #F3F4F5!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sb-btn-grey:hover{ background: #fff!important; color: #141B38!important; border: 1px solid #DCDDE1!important; } .sb-btn-grey:focus, .sb-btn-grey:active{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } /*dark*/ .sb-btn-dark{ background: #2C324C!important; color: #fff!important; } .sb-btn-dark:hover{ background: #434960!important; color: #fff!important; } .sb-btn-dark:focus, .sb-btn-dark:active{ background: #141B38!important; color: #fff!important; } /*orange*/ .sbi-btn-orange{ background: #FE544F!important; color: #fff!important; } .sbi-btn-orange:hover{ background: #F37036!important; color: #fff!important; } .sbi-btn-orange:focus, .sbi-btn-orange:active{ background: #BC120E!important; color: #fff!important; } /*red*/ .sbi-btn-red{ background: #D72C2C!important; color: #fff!important; } .sbi-btn-red:hover{ background: #DF5757!important; color: #fff!important; } .sbi-btn-red:focus, .sbi-btn-red:active{ background: #841919!important; color: #fff!important; } /*red*/ .sbi-btn-blue{ background: #0068A0!important; color: #fff!important; } .sbi-btn-blue:hover{ background: #0096CC!important; color: #fff!important; } .sbi-btn-blue:focus, .sbi-btn-blue:active{ background: #004D77!important; color: #fff!important; } /*grey*/ .sbi-btn-grey{ background: #F3F4F5!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } .sbi-btn-grey:hover{ background: #fff!important; color: #141B38!important; border: 1px solid #DCDDE1!important; } .sbi-btn-grey:focus, .sbi-btn-grey:active{ background: #E8E8EB!important; color: #141B38!important; border: 1px solid #D0D1D7!important; } /*dark*/ .sbi-btn-dark{ background: #2C324C!important; color: #fff!important; } .sbi-btn-dark:hover{ background: #434960!important; color: #fff!important; } .sbi-btn-dark:focus, .sbi-btn-dark:active{ background: #141B38!important; color: #fff!important; } /*disabled*/ .sb-btn-orange[data-active="false"], .sb-btn-blue[data-active="false"], .sb-btn-red[data-active="false"], .sb-btn-grey[data-active="false"], .sb-btn-dark[data-active="false"]{ background: #E8E8EB !important; color: #8C8F9A !important; } /* * Social Colors */ /*Facebook*/ .sb-cl-facebook, .sb-clhv-facebook:hover{ color: #006BFA!important; } .sbi-bg-facebook, .sbi-bghv-facebook:hover{ background: #006BFA!important; } /*Instagram*/ .sb-cl-instagram, .sb-clhv-instagram:hover{ color: #BA03A7!important; } .sbi-bg-instagram, .sbi-bghv-instagram:hover{ background: #BA03A7!important; } /*Twitter*/ .sb-cl-twitter, .sb-clhv-twitter:hover{ color: #1B90EF!important; } .sbi-bg-twitter, .sbi-bghv-twitter:hover{ background: #1B90EF!important; } /*YouTube*/ .sb-cl-youtube, .sb-clhv-youtube:hover{ color: #EB2121!important; } .sbi-bg-youtube, .sbi-bghv-youtube:hover{ background: #EB2121!important; } /*Linkedin*/ .sb-cl-linkedin, .sb-clhv-linkedin:hover{ color: #007bb6!important; } .sbi-bg-linkedin, .sbi-bghv-linkedin:hover{ background: #007bb6!important; } /*Mail*/ .sb-cl-mail, .sb-clhv-mail:hover{ color: #666!important; } .sbi-bg-mail, .sbi-bghv-mail:hover{ background: #666!important; } .sb-cursor-pointer{ cursor: pointer; } .sbi-stck-el.sbi-stck-el-upgrd svg path{ fill: #fff!important; } /*Buttons*/ .sb-btn{ display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 9px 38px; font-style: normal; font-weight: 500; font-size: 14px; line-height: 17px; border-radius: 2px; cursor: pointer; color: #fff; outline: none; box-shadow: none; border: none;; } .sb-btn:focus{ box-shadow: none; } .sbi-small-chevron svg{ width: 6px; height: 8px; top: 14px; left: 18px; } .sb-btn-right-icon{ display: flex; justify-content: flex-start; padding: 15px 12px; } .sb-btn-right-txt{ display: flex; justify-content: flex-start; align-items: center; line-height: 1em; } .sb-btn-right-txt svg{ float: left; margin-right: 10px; } .sb-btn-right-chevron{ width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); margin-left: auto; margin-right: 10px; } /*Add Source*/ /* Add new Source Popup */ .sbi-fb-popup-cls{ height: 14px; width: 14px; position: absolute; cursor: pointer; right: 17px; top: 17px; z-index: 3; } .sbi-fb-center-boss{ display: flex; justify-content: center; align-items: center; } .sbi-fb-popup-inside{ left: 80px; max-width: 1172px; width: calc(85% - 200px); background: #fff; color: #141B38; position: relative; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); border-radius: 2px; overflow-y: auto; max-height: 80vh; } .sbi-fb-feedtypes-popup.sbi-fb-popup-inside{ width: 1172px; max-width: calc(85% - 200px); } .sbi-fb-extensions-pp-ctn .sbi-fb-popup-inside{ max-width: 880px!important; } .sbi-fb-popup-inside.sbi-narrower-modal { max-width: 576px; } .sbi-fb-popup-inside.sb-onboarding-tooltip { overflow-y: visible !important; } @media all and (max-width: 960px) { .sbi-fb-popup-inside { left: 20px; max-width: 920px; width: calc(85% - 20px); } } .sbi-fb-embed-popup{ width: 575px; } .sbi-fb-source-pp-customizer h5,.sbi-fb-embed-popup h5{ font-size: 24px; padding: 0 20px; margin-top: 25px; margin-bottom: 15px; } .sbi-fb-feedtypes-popup h5{ font-size: 26px; padding: 0 20px; margin-top: 25px; margin-bottom: 30px; } .sbi-fb-feedtypes-pp-ctn .sbi-fb-adv-types .sbi-fb-types-list{ margin-bottom: 30px !important } .sbi-fb-srcs-update{ background: var(--cl-orange); font-weight: 600; font-size: 14px; line-height: 160%; height: 38px; } .sbi-fb-srcs-update-footer{ display: flex; align-items: center; border-top: 1px solid #DCDDE1; background: #F9F9FA; } .sbi-fb-srcs-update-footer-txt{ font-size: 18px; line-height: 1.7em; } .sbi-fb-srcs-update-footer-image svg{ width: 100%; height: auto; float: left; } .sbi-fb-srcs-update-footer-txt{ box-sizing: border-box; display: flex; justify-content: center; } .sbi-fb-stp1-elm{ margin-bottom: 30px; float: left; display: flex; } .sbi-fb-source-top .sbi-fb-stp1-elm:first-of-type{ justify-content: center; align-items: center; padding-bottom: 30px; border-bottom: 1px solid #D0D1D7; } .sbi-fb-stp1-event{ padding-bottom: 0px!important; border-bottom: none!important; padding-right: 20%; align-items: flex-start!important; } .sbi-fb-stp1-elm-desc > a{ font-weight: 600; text-decoration: underline; color: #2A65DB; } .sbi-fb-stp-src-ctn, .sbi-flex-center-center{ display: flex; justify-content: center; align-content: center; } .sbi-fb-stp-src-type{ display: flex; justify-content: center; align-content: center; font-size: 13px; font-weight:400; cursor: pointer; margin-left: 20px; color: #434960; white-space: nowrap; } .sbi-fb-stp-src-type[data-active="true"]{ font-weight:600; color: #141B38; } .sbi-not-sure-wrap span svg { margin-right: 5px; } .sbi-not-sure-wrap:hover .sbi-not-sure-tooltip{ display: block; } .sbi-fb-stp1-elm-ic{ width: 28px; height: 28px; border-radius: 35px; background: #F3F4F5; display: flex; justify-content: center; align-items: center; font-weight: 500; flex: none; } .sbi-fb-stp1-elm-head{ font-size: 16px; font-weight: 600; } .sbi-fb-stp1-elm-desc{ font-size: 15px; margin-top: 4px; line-height: 1.3em; color: #5F6368; } .sbi-fb-source-btm-hd{ font-size: 15px; font-weight: 500; } .sbi-fb-src-back-top i{ font-size: 12px; margin-right: 10px; } .sbi-fb-source-account-info{ background: #F3F4F5; color: #8C8F9A; display: flex; align-items: center; padding: 6px 6px 6px 12px; font-size: 15px; } .sbi-fb-source-list { display: grid; grid-template-columns: 49.5% 49.5%; grid-column-gap: 1%; margin-top: 10px; max-height: calc(80vh - 360px); overflow-y: auto; min-height: 80px; } .sbi-fb-source-account-info strong{ color: #141B38; } .sbi-fb-source-btn{ margin-top: 60px; color: #fff; display: flex; justify-content: center; align-items: center; background: #0068A0; cursor: pointer; padding: 10px 20px; border-radius: 3px; font-size: 15px; font-weight: 500; border: none; } .sbi-fb-icon-success{ position: relative; width: 30px; height: 20px; margin-right: 10px; } .sbi-fb-icon-success:before{ content: ''; position: absolute; width: 13px; height: 5px; top: 4px; border-left: 3px solid currentColor; border-bottom: 3px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-fb-source-inp-label,.sbi-fb-wh-label{ font-size: 14px; color: #434960; } .sbi-fb-source-mnl-type .sbi-fb-stp-src-ctn{ justify-content: flex-start; margin-bottom: 20px; margin-top: 10px; } .sbi-fb-source-mnl-type .sbi-fb-stp-src-ctn .sbi-fb-stp-src-type{ margin-left: 0px; margin-right: 20px } .sbi-fb-source-inp,.sbi-fb-wh-inp{ border-radius: 0px !important; outline: none ; margin-top: 5px; border: 1px solid #D0D1D7 !important; margin-bottom: 20px; height: 35px; line-height: 35px; } .sbi-fb-sec-heading span{ font-size:14px; color: #434960; line-height: 1.7em; margin-top: 10px; display: block; } #sbi-builder-app .sbi-fb-sec-heading span { margin-top: 0; } .sbi-fb-sec-heading { margin-bottom: 10px; } .sbi-fb-slctsrc-content,.sbi-fb-section-wh-insd{ padding: 40px; } .sbi-fb-slctsrc-ctn h4,.sbi-fb-section-wh-insd h4{ font-size: 20px; padding: 0px; margin: 0px; } .sbi-fb-srcs-item{ width: 100%; cursor: pointer; height: 62px; margin-top: 10px; border-radius: 3px; border: 1px solid #E7E7E9; display: flex; position: relative; } .sbi-connecting-account-item { display: flex; align-content: center; align-items: center; position: relative; box-sizing: border-box; height: 62px; width: 208px; margin: auto; padding: 12px; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 4px 5px rgba(0, 0, 0, 0.05); border-radius: 4px; } .sbi-fb-source-step4 { max-width: 576px; } .sbi-source-account-box { padding: 32px; background-color: #F3F4F5; } .sb-details-wrap { align-items: center; } .sbi-connecting-account-item .sbi-fb-srcs-item-avatar { margin-right: 8px; } .sbi-fb-srcs-item .sbi-fb-srcs-item-avatar { margin-right: 10px; } .sbi-fb-srcs-item[data-disabled="true"]{ background: #F3F4F5; } .sbi-fb-stp-src-type[data-disabled="true"], .sbi-fb-stp-src-type[data-disabled="true"] .sbi-fb-chbx-round{ color: #8C8F9A !important; cursor: default; } .sbi-fb-stp-src-type[data-disabled="true"] { position: relative; } .sbi-fb-srcs-item[data-disabled="true"] .sbi-fb-srcs-item-inf{ opacity: .55; } .sbi-fb-srcs-item:hover{ border-color: #86D0F9; } .sbi-fb-srcs-item[data-active="true"]{ border-color: #0096cc; } .sbi-fb-source-top .sbi-fb-srcs-item{ margin-bottom: 0px; } .sbi-fb-srcs-new{ display: flex; justify-content: center; align-items: center; font-size: 16px; color: #0096CC; background: #EBF5FF; font-weight: 600; border: 1px solid #EBF5FF; } .sbi-fb-srcs-new i{ font-size: 14px; padding: 0 10px; margin-left: -10px; } .sbi-fb-srcs-item-chkbx{ width: 40px; height: inherit; display: flex; justify-content: center; align-items: center; margin: 0px 7px; } .sbi-fb-srcs-item-chkbx-ic,.sbi-fb-chbx-round{ width: 16px; height: 16px; box-sizing: border-box; position: relative; border-radius: 50px; border: 2px solid #8c8f9a; } [data-multifeed="active"] .sbi-fb-srcs-item-chkbx-ic{ border-radius: 2px; } [data-active="true"] .sbi-fb-srcs-item-chkbx-ic, [data-active="true"] > .sbi-fb-chbx-round, .sbi-fb-source-popup [data-active="true"] > .sbi-fb-chbx-round{ border-color: #0096cc; background: #0096cc; } [data-multifeed="active"] [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before{ content: ''; position: absolute; width: 8px; height: 3px; border-left: 2px solid #fff; border-bottom: 2px solid #fff; top: 2px; right: 1px; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } [data-multifeed="inactive"] [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before, [data-active="true"] > .sbi-fb-chbx-round:before, .sbi-fb-source-popup .sbi-fb-source-list [data-active="true"] .sbi-fb-srcs-item-chkbx-ic:before{ content: ''; position: absolute; height: 6px; width: 6px; background: #fff; border-radius: 25px; left: 3px; top: 3px; } .sbi-fb-srcs-item-avatar{ display: flex; width: 42px; height: inherit; justify-content: center; align-items: center; } .sbi-fb-srcs-item-avatar img{ width: 42px; height: 42px; border-radius: 50%; background: #eee; } .sbi-fb-srcs-item-inf{ width: 100%; height: inherit; display: flex; justify-content: center; flex-direction: column; } .sbi-fb-srcs-item-name{ color: #141B38; font-weight: 600; } .sbi-fb-srcs-item-name-event{ font-size: 10px; font-weight: 500; color: #777; } .sbi-fb-srcs-item-type{ color: #434960; font-weight: 600; text-transform: uppercase; display: flex; align-items: center; } .sbi-fb-srcs-item-type svg{ fill: currentColor; } [data-type="page"] .sbi-fb-srcs-item-type svg{ width: 11px; } .sbi-fb-srcs-back{ margin-right: auto; } /*Full Screen Window*/ .sb-fs-boss{ position: fixed; height: 100vh; width: 100%; left: 0; top: 0; bottom: 0; right: 0; background: rgba(0,0,0,.4); z-index: 9989; } .sb-dialog-popup{ width: 575px!important; min-height: 250px; } .sb-dialog-remove-source{ background: #F3F4F5; padding: 40px 20px; display: flex; justify-content: center; align-items: center; } .sb-dialog-remove-source .sbi-fb-srcs-item{ background: #fff; width: 280px; padding-left: 20px; box-sizing: border-box; margin-top: 0px; } .sb-dialog-popup-content{ display: flex; justify-content: center; align-items: center; text-align: center; flex-direction: column; padding: 38px 12%; } .sb-dialog-popup-content strong{ font-size: 22px; color: #141B38; display: block; margin-bottom: 15px; line-height: 160%; } .sb-dialog-popup-content span{ font-size: 16px; line-height: 1.5em; color: #434960; } .sb-dialog-popup-actions{ display: flex; justify-content: center; align-items: center; margin-top: 25px; } .sb-dialog-popup-actions button{ width: 100%; margin: 4px 4px; cursor: pointer; height: 42px; } .sb-full-screen-loader{ position: absolute; width: 100%; height: calc(100vh - 32px); background: #f0f0f1; z-index: 999999; overflow: hidden; display: none; opacity: 0; visibility: hidden; justify-content: center; align-items: center; flex-direction: column; top: 0px; } .sb-full-screen-loader[data-show="shown"]{ display: flex; opacity: 1; visibility: visible; } .sb-full-screen-loader-logo{ width: 190px; height: 190px; position: relative; margin-bottom: 40px; margin-top: -55px; } .sb-full-screen-loader-logo svg { height: auto; } .sb-full-screen-loader-border{ width: inherit; height: inherit; box-sizing: border-box; border: 6px solid green; left: 0; top: 0; position: absolute; border-radius: 50%; } .sb-full-screen-loader-img{ width: inherit; height: inherit; display: flex; justify-content: center; align-items: center; position: absolute; top: 0px; left: 0px; z-index: 2; } .sb-full-screen-loader-img svg{ float: left; width: 60px; fill: #FE544F; } .sb-full-screen-loader-txt{ color: #434960; font-size: 24px; font-weight: 600; } .sb-full-screen-loader-spinner, .sb-full-screen-loader-spinner:before, .sb-full-screen-loader-spinner:after { border-radius: 50%; } .sb-full-screen-loader-spinner { color: #FE544F; position: relative; width: 190px; height: 190px; box-shadow: inset 0 0 0 6px; -webkit-transform: translateZ(0); transform: translateZ(0); } .sb-full-screen-loader-spinner:before, .sb-full-screen-loader-spinner:after { position: absolute; content: ''; } .sb-full-screen-loader-spinner:before { width: 100px; height: 200px; background: #f0f0f1; border-radius: 190px 0 0 190px; top: -1px; left: -8px; -webkit-transform-origin: 5.1em 5.1em; transform-origin: 100px 100px; -webkit-animation: sbi-loader-spinner 2s infinite ease 1.5s; animation: sbi-loader-spinner 2s infinite ease 1.5s; } .sb-full-screen-loader-spinner:after { width: 97px; height: 192px; background: #f0f0f1; border-radius: 0 190px 190px 0; top: -1px; left: 94px; -webkit-transform-origin: 1px 95px; transform-origin: 1px 95px; -webkit-animation: sbi-loader-spinner 2s infinite ease; animation: sbi-loader-spinner 2s infinite ease; } @-webkit-keyframes sbi-loader-spinner { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes sbi-loader-spinner { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } /* Social Wall Popup */ .sbi-fb-extpp-social-wall-graphic { display: flex; flex-direction: column; align-items: center; padding-bottom: 78px } .sbi-graphic-row, .sbi-fb-social-wall-between { position: relative; } .sbi-graphic-row-main { display: flex; justify-content: center; flex-direction: row; align-items: center; } .sbi-fb-social-wall-group { display: flex; flex-direction: column; align-items: center; width: 13%; margin: 1.5%; } .sbi-fb-social-wall-group p { margin: 0; text-align:center; } .sbi-fb-social-wall-between.sbi-fb-social-wall-between-instagram svg { margin-top:120%; } .sbi-fb-social-wall-between.sbi-fb-social-wall-between-facebook svg { margin-top:40%; } .sbi-fb-social-wall-between.sbi-fb-social-wall-between-twitter svg { margin-top:60%; } .sbi-fb-social-wall-end { position: absolute; right: -1%; top: 40%; } .sbi-graphic-bottom { width: 100%; display: flex; justify-content: center; flex-direction: row; align-items: center; margin-top:3%; } .sbi-all-in-same { display: flex; justify-content: center; flex-direction: row; align-items: center; height: 38px; width: 72.5%; /*background: #FFFFFF;*/ /*box-shadow: 0px 6px 7px rgba(0, 26, 119, 0.07), 0px 3px 4px rgba(0, 26, 119, 0.06), 0px 1.80196px 2.25245px rgba(0, 26, 119, 0.05), 0px 0.749837px 0.937296px rgba(0, 26, 119, 0.1137);*/ /*border-radius: 3px;*/ border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; } .sbi-fb-extpp-social-wall .sbi-fb-extpp-bottom { background: #F3F4F5; } .sbi-fb-social-wall-end-arrow { position: relative; } .sbi-arrow-head { position: absolute; bottom: 1%; left: 39%; } /* To Builder */ .sbi-fb-type-el[data-active="true"]:before { content: ''; position: absolute; width: 24px; height: 24px; right: 0px; top: 0px; z-index: 2; border-radius: 0 0 0 2px; background: var(--cl-orange); } .sbi-fb-type-el { display: flex; flex-direction: column; align-items: flex-start; padding: 0; position: relative; background: #fff; border: 1px solid #D8D8D8; border-radius: 3px; cursor: pointer; box-sizing: border-box; } .sbi-fb-slctf-back span { font-weight: 600; } .sbi-fb-slctfd-action { padding: 16px 54px; position: fixed; bottom: 0; background: #f0f0f1; width: calc(100% - 160px); } .sbi-fb-wrapper { max-width: 100%; position: relative; margin: auto; color: #141B38; } .sbi-fb-create-ctn { float: left; margin-top: 104px; padding: 0 54px 65px; } .sbi-fb-extpp-btns a { height: 38px; cursor: pointer; position: relative; border-radius: 3px; font-style: normal; font-weight: 600; font-size: 14px; line-height: 160%; display: flex; justify-content: center; align-items: center; box-sizing: border-box; } .sbi-fb-extpp-lite-btn { display: flex; align-items: center; font-size: 14px; font-weight: 600; padding: 6px 11px; color: #0068A0; background: #fff; border: 1px solid #DCDDE1; margin-bottom: 14px; } .sbi-fb-extpp-lite-btn svg { fill: currentColor; width: 16px; height: 16px; float: left; margin-right: 10px; } .sbi-fb-stp-src-type .sbi-fb-chbx-round { margin-right: 8px; margin-top: 2px; } #sbi-builder-app .sbi-fb-stp-src-type { display: flex; justify-content: center; align-content: center; font-size: 14px; font-weight: 400; cursor: pointer; margin-left: 20px; color: #434960; } .sbi-csz-name-ed-btn { width: 28px; height: 28px; cursor: pointer; margin: 0 10px; background: #E8E8EB; border: 1px solid #E8E8EB; outline: none; border-radius: 2px; } .sbi-csz-name-ed-btn svg { width: 16px; height: 14px; fill: #141B38; float: left; margin-left: -1px; } .sbi-csz-name-ed-btn:focus, .sbi-csz-name-ed-btn:hover { outline: none; background-color: #d9d9dc; border-color: #d9d9dc; } .sb-preview-chooser-btn, .sb-preview-chooser-btn:focus { width: 38px; height: 32px; display: flex; justify-content: center; align-items: center; cursor: pointer; float: left; border: 0; background: unset; margin: 0 1px; outline: none; } .sb-customizer-sidebar { position: fixed; z-index: 100; width: 375px; box-shadow: 4px 0px 14px rgb(0 0 0 / 5%), 1px 0px 4px rgb(0 0 0 / 10%); background: #fff; left: 160px; top: 98px; overflow: auto; bottom: 0px; padding-bottom: 50px; } .sb-customizer-sidebar-breadcrumb a, .sb-customizer-sidebar-breadcrumb span { display: inline-block; position: relative; cursor: pointer; color: #434960; text-transform: uppercase; font-size: 10px; line-height: 160%; letter-spacing: 0.02em; padding: 0 5px 0 4px; height: 20px; font-weight: 700; } .sb-control-elem-ctn { display: flex; color: #434960; padding: 20px 20px; } .sb-control-toggle-icon svg { width: 13px; float: left; fill: #434960; } .sb-control-elem-ctn .sb-control-toggle-elm[data-active="true"] { display: flex; color: #141B38; padding: 0 15px; } .sb-control-elem-ctn .sb-control-toggle-elm[data-active="true"] svg { fill: #141B38; } .sb-control-elem-ctn .sb-control-toggle-elm[data-disabled="true"] { color: #8C8F9A; } .sb-control-elem-ctn .sb-control-toggle-elm[data-disabled="true"] svg { fill: #8C8F9A; } .sb-control-elem-ctn[data-layout="block"] input[type="number"] { height: 36px; background: #FFFFFF; border-radius: 2px 0 0 2px !important; } .sb-control-input-info { display: flex; justify-content: center; align-items: center; background: #F3F4F5; padding: 0 8px; font-weight: normal; font-size: 14px; line-height: 160%; color: #434960; border: 1px solid #D0D1D7; border-left: none; border-radius: 0 2px 2px 0 !important; } .sb-control-elem-output input[type="text"], .sb-control-elem-output input[type="number"]{ border-radius: 1px !important; } .sb-control-colorpicker-ctn .minicolors-theme-default.minicolors-position-right .minicolors-swatch { left: auto; right: 1px; top: 1px; width: 35px; height: 35px; background: #F9F9FA; border: 0px; border-radius: 2px; } .sb-control-colorpicker-ctn[data-picker-style="reset"] .minicolors-input { background: #F3F4F5!important; border: 1px solid #DCDDE1!important; height: 38px; } .sb-customizer-sidebar-breadcrumb svg { position: relative; left: auto; top: auto; margin-right: 9px; } .sb-customizer-sidebar-breadcrumb { display: flex; justify-content: flex-start; align-items: center; margin-bottom: 15px; } .sbi-fb-srcs-info-item span { font-size: 13px; line-height: 1.5em; color: #434960; font-weight: 400; display: inline-block; word-break: break-all; width: calc(100% - 80px); padding: 0 15px; box-sizing: border-box; } /* Onboarding */ #sbi-builder-app .sb-onboarding-tooltip { display: none; position: absolute; min-height: auto; width: 460px; max-width: 100%; padding: 0; border-radius: 2px; } #sb-onboarding-tooltip-multiple-2, #sb-onboarding-tooltip-multiple-3{ width: 528px; } #sb-onboarding-tooltip-single-2 { width: 402px; } .sb-onboarding-active .sb-onboarding-highlight .sbi-fb-btn.sbi-fb-btn-new, .sb-onboarding-active .sb-positioning-wrap.sb-onboarding-highlight, .sb-onboarding-active .sbi-fd-lst-bigctn .sbi-table-wrap.sb-onboarding-highlight, .sb-onboarding-active .sbi-fb-lgc-ctn.sb-onboarding-highlight, .sb-onboarding-active .sbi-fb-lgc-ctn .sbi-legacy-table-wrap.sb-onboarding-highlight, .sb-onboarding-active .sb-customizer-sidebar-tab.sb-onboarding-highlight, .sb-onboarding-active .sbi-fb-header.sb-onboarding-highlight{ position: relative; z-index: 100000; } .sb-onboarding-active .sbi-fd-legacy-feed-toggle { display: none; } .sbi-legacy-table-wrap.sb-onboarding-highlight { clear: both; } #sbi-builder-app .sb-onboarding-tooltip-1 { top: 50px; left: 8px; } #sb-onboarding-tooltip-single-2 { bottom: -179px; top: auto; left: 68%; margin-left: -201px; } #sb-onboarding-tooltip-multiple-2, #sb-onboarding-tooltip-multiple-3{ top: -200px; left: 20%; } #sb-onboarding-tooltip-multiple-3 { top: -210px; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-wrapper { display: flex; justify-content: flex-end; } #sbi-builder-app .sb-positioning-wrap { width: 432px; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-popup-cls { position:absolute; width: 12px; height: 12px; top: 12px; right: 12px; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-popup-cls svg { width: 12px; height: 12px; } #sbi-builder-app .sb-onboarding-tooltip h3 { font-size: 16px; color: #141B38; line-height: 160%; font-weight: 600; margin: 0; } #sbi-builder-app .sb-onboarding-step { font-style: normal; font-weight: normal; font-size: 13px; line-height: 160%; color: #434960; margin: 2px 0 20px; display: block; } .sbi-onboarding-next, .sbi-onboarding-previous{ color: #353A41; background: #F3F4F5; border: 1px solid #DCDDE1; margin-left: 10px; } .sbi-onboarding-previous[data-active=false]{ pointer-events: none; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-hd-btn { margin-right: 0; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-hd-btn i { margin: 0; } .sbi-onboarding-finish{ margin-left: 10px; padding: 0 32px; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-hd-btn[data-active="false"] { background-color: #e8e8eb; color: #8c8f99; } #sbi-builder-app .sb-onboarding-tooltip .sbi-fb-hd-btn[data-active="false"]:hover { cursor: default; } .sb-step-counter-wrap span { font-style: normal; font-weight: bold; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; color: #141B38; } #sbi-builder-app .sb-onboarding-tooltip .sb-pointer { position: absolute; left: 50px; top: -10px; } #sbi-builder-app .sb-pointer.sb-bottom-pointer { top: auto; bottom: -14px; } #sb-onboarding-tooltip-single-2 .sb-pointer { left: 193px; } #sb-onboarding-tooltip-multiple-2:before, #sb-onboarding-tooltip-multiple-3:before{ bottom: -8px; } #sbi-builder-app .sb-onboarding-top-row { padding: 20px 44px 0 24px; } #sbi-builder-app .sb-onboarding-bottom-row { display: flex; flex-direction: row; justify-content: space-between; align-items: center; padding: 8px 16px 12px 24px; } #sbi-builder-app #sb-onboarding-tooltip-customizer-1 { position:absolute; right: 210px; left: auto; top: 84px; } #sbi-builder-app #sb-onboarding-tooltip-customizer-1 .sb-pointer { right: 110px; left: auto; } .sb-customizer-sidebar.sb-onboarding-highlight { z-index: 9999; overflow: visible; } #sb-onboarding-tooltip-customizer-2, #sb-onboarding-tooltip-customizer-3 { z-index: 100000; top: 80px; } #sb-onboarding-tooltip-customizer-3 { left: 171px; } #sbi-builder-app #sb-onboarding-tooltip-customizer-3 .sb-pointer{ left: 100px; } .sb-onboarding-active .sb-customizer-sidebar-tab-ctn, .sb-onboarding-active .sb-customizer-sidebar-sec-ctn, .sb-onboarding-active .sbi-csz-header .sbi-csz-header-insider{ /*pointer-events: none !important;*/ } /* Misc Tooltip */ .sbi-not-sure-tooltip { left: -360px; top: -110px; } .sbi-not-sure-tooltip .sb-pointer { bottom: -17px !important; left: 390px; } .sbi-not-sure-tooltip { display: none; } .sbi-not-sure-tooltip-icon:hover .sbi-not-sure-tooltip { display: block; padding: 12px 16px 16px; width: 400px; } /* Add new Source Popup */ .sbi-fb-popup-cls{ height: 14px; width: 14px; position: absolute; cursor: pointer; right: 17px; top: 17px; z-index: 3; } .sbi-fb-center-boss{ display: flex; justify-content: center; align-items: center; } .sbi-fb-left-boss{ display: flex; justify-content: left; align-items: center; } .sbi-fb-embed-popup,.sbi-fb-dialog-popup{ width: 575px; } .sbi-fb-dialog-popup{ min-height: 250px; } .sbi-fb-source-pp-customizer .sbi-fb-srcslist-ctn{ grid-template-columns: 32.7% 32.7% 32.7%; grid-column-gap: 1%; } .sbi-fb-srcs-desc{ width: 55%; font-style: normal; font-weight: normal; font-size: 14px; line-height: 160%; color: #434960; box-sizing: border-box; margin-bottom: 29px; } #sbi-builder-app .sbi-fb-source-pp-customizer h3{ margin-bottom: 6px; } #sbi-builder-app .sbi-fb-embed-popup h3 { padding: 23px 25px 0; margin-bottom: 0; } #sbi-builder-app .sbi-fb-embed-popup .sbi-fb-embed-step-2 h3 { padding: 0 0 0 29px; } .sbi-fb-feedtypes-popup h5{ font-size: 26px; padding: 0 20px; margin-top: 25px; margin-bottom: 30px; } .sbi-fb-feedtypes-pp-ctn .sbi-fb-adv-types .sbi-fb-types-list{ margin-bottom: 30px !important } .sbi-fb-feedtypes-popup .sbi-fb-types, .sbi-fb-feedtypes-popup .sbi-fb-adv-types { padding: 0; } .sbi-fb-source-top{ padding: 22px 19px 28px; } #sbi-builder-app .sbi-fb-source-step1 .sbi-fb-source-top h3{ margin-bottom: 40px; } #sbi-builder-app .sbi-fb-source-step3 .sbi-fb-source-top h3 { margin-bottom: 30px; } #sbi-settings .sbi-fb-source-step4 .sbi-fb-stp1-elm-desc { max-width: 470px; margin-bottom: 26px; } #sbi-settings .sb-step-text { color: #434960; } .sbi-fb-srcs-update{ background: var(--cl-orange); font-weight: 600; font-size: 14px; line-height: 160%; height: 38px; } .sbi-fb-srcs-update svg{ margin-right: 10px; } .sbi-fb-srcs-update-footer{ display: flex; align-items: center; border-top: 1px solid #DCDDE1; background: #F9F9FA; } .sbi-fb-srcs-update-footer-txt{ font-size: 18px; line-height: 1.7em; } .sbi-fb-srcs-update-footer-btn{ } #sbi-builder-app .sbi-fb-srcs-update-footer-btn a{ height: 48px; padding: 0 20px 0 24px; } .sbi-fb-srcs-update-footer-image{ width: 26%; margin-right: 7%; } #sbi-builder-app .sbi-fb-srcs-update-footer-btn a svg { position: relative; top: auto; right: auto; width: auto; height: auto; margin-left: 15px; } .sbi-fb-srcs-update-footer-image svg{ width: 100%; height: auto; float: left; } .sbi-fb-srcs-update-footer-txt{ box-sizing: border-box; display: flex; justify-content: center; width: 38%; margin-right: 7%; } .sbi-fb-stp1-elm{ margin-bottom: 20px; float: left; display: flex; } .sbi-fb-source-top .sbi-fb-stp1-elm:first-of-type{ justify-content: center; align-items: center; padding-bottom: 24px; border-bottom: 1px solid #D0D1D7; } .sbi-fb-stp1-event{ padding-bottom: 0px!important; border-bottom: none!important; padding-right: 11%; align-items: flex-start!important; } .sbi-fb-stp1-elm-desc > a{ font-weight: 600; text-decoration: underline; color: #2A65DB; } .sbi-fb-stp-src-ctn{ display: flex; justify-content: center; align-content: center; } #sbi-builder-app .sbi-fb-stp-src-type{ display: flex; justify-content: center; align-content: center; font-size: 13px; font-weight:400; cursor: pointer; margin-left: 20px; color: #434960; } .sbi-fb-stp-src-type .sbi-fb-chbx-round{ margin-right: 8px; margin-top: 2px; } .sbi-fb-stp-src-type[data-active="true"]{ font-weight:600; color: #141B38; } .sbi-fb-stp1-elm-ic{ width: 28px; height: 28px; border-radius: 35px; background: #F3F4F5; display: flex; justify-content: center; align-items: center; font-weight: 500; flex: none; transform: translate(0, -2px); } .sbi-fb-stp1-elm-txt{ margin-left: 16px; margin-right: 21%; width: 100%; } .sbi-fb-stp1-elm-head{ font-size: 14px; font-weight: 600; color: #141B38; } .sbi-fb-stp1-elm-desc{ font-size: 13px; margin-top: 4px; line-height: 150%; color: #888a8e; } .sbi-fb-stp1-event .sbi-fb-stp1-elm-desc { margin-top: 4px; } .sbi-fb-stp1-elm-act .sb-btn.sbi-fb-stp1-connect{ padding: 8px 20px 8px 40px; background: #0068A0; position: relative; font-style: normal; font-weight: 600; font-size: 14px; line-height: 160%; } .sbi-fb-stp1-connect svg{ position: absolute; top: 10px; right: 0; bottom: 0; left: 13px; width: 17px; fill: currentColor; } .sbi-fb-stp1-connect path{ fill: currentColor; } .sbi-fb-source-bottom{ padding: 18px 20px; background: #F3F4F5; display: flex; align-items: center; border-radius: 0 0 2px 2px; } .sbi-manual-question { display: flex; align-items: center; } .sbi-manual-question svg{ margin-right: 23px; float: left; } .sbi-fb-source-btm-hd{ font-size: 14px; font-weight: 500; } .sbi-fb-src-add-manual{ margin-left: auto; padding: 8px 20px 8px 40px; } .sbi-fb-src-add-manual svg{ position: absolute; top: 11px; right: 0; bottom: 0; left: 13px; fill: currentColor; } #sbi-builder-app .sbi-fb-source-step2 .sbi-fb-source-top h3 { margin-bottom: 35px; } #sbi-builder-app .sbi-fb-source-step4 .sbi-fb-source-top h3, #sbi-builder-app .sbi-fb-source-step4 .sbi-fb-source-top h4{ margin-bottom: 8px; } #sbi-builder-app .sbi-fb-source-step4 .sbi-fb-stp1-elm-desc { max-width: 470px; margin-bottom: 26px; } .sbi-fb-src-add-manual i{ font-size: 12px; margin-right: 10px; } .sbi-fb-src-back-top{ float: left; font-style: normal; font-weight: 600; font-size: 12px; line-height: 160%; letter-spacing: 0.05em; text-transform: uppercase; cursor: pointer; color: #141B38; margin-bottom: 10px; display: flex; justify-content: center; align-items: center; } .sbi-fb-src-back-top svg{ margin-left: 6px; margin-right: 10px; } .sbi-fb-source-account-info{ background: #F3F4F5; padding: 6px 6px 6px 12px; display: flex; align-items: center; } .sbi-fb-source-list{ display: grid; grid-template-columns: 49.4% 49.4%; grid-column-gap: 1.2%; margin-top: 8px; } .sbi-fb-source-popup.sbi-fb-popup-inside .sbi-fb-srcs-item { box-sizing: border-box; margin: 1.2% 0; } .sbi-fb-source-account-info img{ width: 23px; height: 23px; border-radius: 23px; background: #fafafa; margin-left: 10px; margin-right: 10px; } .sbi-fb-source-account-info strong{ color: #141B38; } .sbi-fb-src-change{ padding: 7px 20px 7px 40px; margin-left: auto; } .sbi-fb-src-change svg{ position: absolute; top: 11px; right: 0; bottom: 0; left: 13px; fill: currentColor; } .sbi-fb-source-btn{ margin-top: 10px; color: #fff; display: flex; justify-content: center; align-items: center; background: #0068A0; cursor: pointer; padding: 8px 20px; line-height: 160%; border-radius: 2px; font-size: 14px; font-weight: 500; border: none; text-decoration: none; } #sbi-builder-app .sbi-fb-source-step3 .sbi-fb-source-btn { margin-top: 45px; } #sbi-builder-app .sbi-fb-source-step3 .sbi-fb-src-back-top { margin-bottom: 4px; } .sbi-fb-icon-success{ position: relative; width: 30px; height: 20px; margin-right: 10px; } .sbi-fb-icon-success:before{ content: ''; position: absolute; width: 13px; height: 5px; top: 4px; border-left: 3px solid currentColor; border-bottom: 3px solid currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-fb-icon-cancel{ position: relative; width: 25px; height: 25px; margin-right: 10px; } .sbi-fb-icon-cancel:before, .sbi-fb-icon-cancel:after{ content: ''; position: absolute; width: 17px; height: 2px; top: 12px; left: 5px; background: currentColor; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-fb-icon-cancel:after{ -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-fb-source-inp-label,.sbi-fb-wh-label{ font-size: 14px; color: #434960; } .sbi-fb-source-mnl-type .sbi-fb-stp-src-ctn{ justify-content: flex-start; margin-bottom: 22px; margin-top: 8px; } #sbi-builder-app .sbi-fb-source-mnl-type .sbi-fb-stp-src-ctn .sbi-fb-stp-src-type{ margin-left: 0; margin-right: 32px } .sbi-fb-source-inp,.sbi-fb-wh-inp{ border-radius: 0px !important; outline: none ; margin-top: 2px; border: 1px solid #D0D1D7 !important; margin-bottom: 20px; height: 38px; line-height: 38px; } .sbi-fb-source-popup h1 { font-style: normal; font-weight: 600; font-size: 36px; line-height: 125%; color: #141B38; margin: 0; } .sbi-fb-source-popup h2 { font-style: normal; font-weight: 600; font-size: 32px; line-height: 125%; margin: 0; } .sbi-fb-source-popup h3 { font-style: normal; font-weight: 600; font-size: 24px; line-height: 120%; margin: 0 0 40px 0; letter-spacing: 0; } .sbi-fb-source-popup h4 { font-style: normal; font-weight: 600; font-size: 18px; line-height: 140%; margin: 0 0 4px 0; } .sbi-fb-slctf-back svg, .sbi-fb-slctf-nxt svg, .sbi-fb-source-btn-next svg{ width: 6px; height: 10px; } .sbi-fb-source-btn-next span { display: inline-block; margin-right: 15px; line-height: 160%; } .sb-single-step { display: flex; align-items: center; margin-bottom: 16px; } .sb-step-number { display: flex; align-items: center; justify-content: center; background: #F3F4F5; border-radius: 30px; width: 24px; height: 24px; margin-right: 16px; } #sbi-builder-app .sb-step-text { color: #434960; } .sb-two-buttons-wrap { box-sizing:border-box; float: left; display: flex; justify-content: center; align-items: center; width: 100%; padding: 0 19px 28px; } .sb-two-buttons-wrap .sbi-fb-source-btn { margin-top: 0; } .sbi-fb-source-step4 .sbi-fb-source-top { padding: 24px 54px 32px; text-align: center; } .sb-two-buttons-wrap > button:first-of-type { margin-right: 12px; } .sb-two-buttons-wrap .sb-question-circle { margin-right: 9px; } #sbi-group-app-tooltip{ cursor: pointer; } .sbi-group-app-screenshot{ display: none; position: absolute; bottom: 92px; left: 50%; margin-left: -325px; z-index: 10; border: 1px solid rgba(0,0,0,0.3); box-shadow: 0 0 0 5000px rgb(0 0 0 / 20%); border-radius: 5px; } #sbi-group-app-tooltip:hover .sbi-group-app-screenshot{ display: block !important; } .sbi-fb-source-btn[data-active = false] { pointer-events: none !important; } .sbi-fb-source-btn[data-active = false] svg path{ fill: #8C8F9A !important; } .sb-directions-p { margin-bottom: 40px; } .sbi-fb-srcs-item-avatar{ display: flex; width: 42px; height: inherit; justify-content: center; align-items: center; } .sbi-fb-srcs-item-avatar img{ width: 36px; height: 36px; border-radius: 50%; background: #eee; } .sbi-fb-srcs-item-inf{ width: 100%; height: inherit; display: flex; justify-content: center; flex-direction: column; } .sbi-fb-srcs-item-name{ font-weight: 600; } .sbi-fb-srcs-item-name-event{ font-size: 10px; font-weight: 500; color: #777; } .sbi-fb-srcs-item-type{ color: #434960; font-weight: 600; text-transform: uppercase; display: flex; align-items: center; } .sb-source-error-wrap { display: flex; justify-content: left; align-items: center; margin-left: 9px; } .sb-source-error-wrap span { font-weight: 600; font-size: 12px; line-height: 160%; color: #D72C2C; margin-left: 5px; } .sbi-fb-source-popup .sb-source-error-wrap { margin-left: 0; } .sb-source-error-wrap a { margin-left: 8px; font-weight: 600; font-size: 12px; line-height: 160%; text-decoration-line: underline; color: #0068A0; } .sb-is-group .sb-details-wrap { position: relative; display: flex; align-items: center; padding: 2px 6px 2px 22px; background: #F3F4F5; border-radius: 2px; } .sb-highlight-admin .sb-details-wrap { padding: 2px 6px 2px 17px; background: #E2F5FF; color: #0068A0; } .sb-highlight-admin span { color: #0068A0; } .sbi-fb-srcs-item-type i{ margin-right: 5px; } .sbi-fb-srcs-item-type svg{ float: left; margin-right: 5px; fill: currentColor; height: 8px; } .sb-has-details .sbi-fb-srcs-item-type svg{ position: absolute; top: 5px; right: 0; bottom: 0; left: 5px; height: 9px; } .sb-has-details .sbi-fb-srcs-item-type.sb-highlight-admin svg { top: 6px; } [data-type="page"] .sbi-fb-srcs-item-type svg{ height: 9px; } .sbi-fb-srcs-back{ margin-right: auto; } .sbi-groups-connect-actions { float: left; } .sb-alert, .sbi-error-ctn .sb-alert{ position: relative; margin: 0 0 38px; padding: 12px 12px 12px 44px; word-break: break-word; background: #FFEFCC } .sbi-connection-error .sb-alert { margin: 20px; } .sbi-connect-actions .sbi-fb-source-btn { margin-top: 0; } .sbi-connect-actions { float: left; } .sbi-connect-actions.sb-alerts-wrap .sb-alert { clear: left; } .sb-alerts-wrap .sb-alert svg, .sb-alert svg, .sbi-error-ctn .sb-alert svg{ position: absolute; top: 13px; left: 13px; } .sb-alert span, .sbi-error-ctn .sb-alert span{ color: #995C00; } #sbi-builder-app .sb-alert span a, .sbi-error-ctn .sb-alert span a{ color: #663D00; font-weight: 600; text-decoration: underline; } #sbi-settings .sbi-fb-source-step1.sbi-has-alert .sbi-fb-source-top h3 { margin-bottom: 12px; } .sbi-groups-connect-actions .sbi-fb-source-btn { margin-top: 0; } /* Install Plugin Modal on Select Source Flow */ .sbi-install-plugin-modal { max-width: 580px; } .sbi-install-plugin-body .sbi-install-plugin-header { height: 106px; background: #F3F4F5; padding: 20px; display: flex; box-sizing: border-box; flex-wrap: wrap; align-items: center; } .sbi-install-plugin-body .sbi-install-plugin-header .sb-plugin-image { background-color: #fff; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); border-radius: 2px; padding: 15px; max-height: 66px; box-sizing: border-box; margin-right: 24px; } .sbi-install-plugin-body .sbi-install-plugin-header h3 { font-size: 18px !important; line-height: 25px !important; display: flex; align-items: center; } .sbi-install-plugin-body .sbi-install-plugin-header h3 span { color: #fff; background: #59AB46; border-radius: 2px; font-size: 10px; line-height: 16px; letter-spacing: 0.08em; text-transform: uppercase; padding: 0px 6px; margin-left: 10px; } .sbi-install-plugin-body .sbi-install-plugin-header p { display: flex; font-size: 12px; line-height: 18px; color: #434960; margin: 5px 0 0 0; } .sbi-install-plugin-body .sbi-install-plugin-header p .sb-author-logo { margin-right: 8px; } .sbi-install-plugin-body .sbi-install-plugin-content { padding: 20px 20px 32px 107px; } .sbi-install-plugin-body .sbi-install-plugin-content p { margin: 0px; font-size: 14px; line-height: 22px; color: #434960; padding-right: 20px; } .sbi-install-plugin-body .sbi-install-plugin-content .sbi-install-plugin-btn { display: flex; align-items: center; justify-content: center; height: 38px; padding: 8px 20px; box-sizing: border-box; transition: all .15s ease-in-out; border-radius: 2px; width: 100%; margin-top: 28px; border: none; font-size: 14px; font-weight: 600; line-height: 160%; cursor: pointer; } .sbi-install-plugin-body .sbi-install-plugin-content .sbi-btn-orange:disabled { color: #8C8F9A !important; background: #E8E8EB !important; cursor: not-allowed; } .sbi-install-plugin-body .sbi-install-plugin-content .sbi-install-plugin-btn span { height: 20px; width: 20px; margin-right: 5px; } .sbi-fb-mr-fd-list button { cursor: pointer; } /* Tooltips */ .sb-control-elem-tltp{ margin-left: 10px; position: relative; } .sb-control-elem-tltp-icon{ float: left; cursor: pointer; } .sb-control-elem-tltp-icon svg{ width: 14px; float: left; } @media (min-width: 768px) and (max-width: 1079px) { .sbi-fb-mr-fd-img { width: 37%; } .sbi-fb-mr-fd-list button:not(:last-child) { margin-bottom: 8px; } } @media (min-width: 768px) and (max-width: 1023px) { .sbi-fb-srcslist-ctn, .sbi-fb-source-pp-customizer .sbi-fb-srcslist-ctn { grid-template-columns: 49.2% 49.2%; gap: 2%; margin-top: 8px; } .sbi-fb-slctfd-action { width: 100%; } .sbi-fb-srcs-item { margin-top: 3px; } .sbi-manual-question { max-width: 390px; } .sbi-fb-feedtypes-popup { left: 0; max-width: calc(100% - 60px); } .sbi-fb-feedtypes-pp-ctn.sbi-fb-center-boss { top: 40px; } } @media (max-width: 767px) { .sbi-fb-feedtypes-pp-ctn.sbi-fb-center-boss { align-items: baseline; } .sbi-fb-feedtypes-popup { max-width: calc(100% - 40px); top: 50px; } #sbi-builder-app .sb-positioning-wrap { width: 130px; } .sbi-fb-embed-popup, .sbi-fb-dialog-popup { width: 100%; max-width: calc(100% - 40px); } .sbi-fb-popup-inside { left: 0; } .sbi-fb-extensions-pp-ctn .sbi-fb-popup-inside.sbi-fb-extensions-popup, .sbi-fb-source-ctn .sbi-fb-popup-inside { max-width: calc(100% - 40px); } .sbi-fb-source-ctn.sbi-fb-center-boss, .sbi-fb-extensions-pp-ctn.sbi-fb-center-boss{ align-items: baseline; } .sbi-fb-extensions-pp-ctn.sbi-fb-center-boss .sbi-fb-popup-inside{ top: 50px; } .sbi-extension-bullet-list { grid-template-columns: 100%; } .sbi-fb-extpp-bottom { padding: 20px; } .sbi-fb-extpp-info { width: 100%; padding-right: 20px; padding-left: 20px; } .sbi-fb-extpp-img { display: none; } .sbi-fb-extpp-top { height: 195px; } .sbi-fb-source-pp-customizer .sbi-fb-srcslist-ctn { grid-template-columns: 99.2%; gap: 2%; margin-bottom: 50px; } .sbi-fb-source-account-info { flex-wrap: wrap; } .sbi-fb-source-account-info > span { width: 100%; } .sbi-fb-source-account-info img { margin-left: 0; } .sbi-fb-source-btn { margin-top: 25px; } .sbi-fb-source-bottom { flex-wrap: wrap; margin-top: 0; } .sbi-fb-src-add-manual { margin-left: 0; margin-top: 15px; } .sbi-fb-types-list { grid-template-columns: 100%; } .sbi-fb-types-list .sbi-fb-type-el { margin-bottom: 10px; } .sbi-fb-create-ctn { margin-top: 90px; padding: 0 20px 65px; } #sbi-builder-app h1 { font-size: 32px; } .sbi-fb-social-wall-between, .sbi-fb-social-wall-end { display: none; } .sbi-graphic-row-main { justify-content: space-between; } .sbi-fb-slctfd-action { width: 100%; } .sbi-fb-mr-feeds { flex-wrap: wrap; margin-bottom: 60px; } .sbi-fb-mr-feeds .sbi-fb-mr-fd-content, .sbi-fb-slctsrc-content, .sbi-fb-section-wh-insd, .sbi-fb-types, .sbi-fb-adv-types { padding: 20px; } .sbi-fb-source-ctn .sbi-fb-popup-inside.sbi-install-plugin-modal { top: 0; } .sbi-fb-mr-fd-list button:not(:last-child) { margin-bottom: 8px; } .sbi-fb-srcs-item { margin-top: 3px; } #sbi-builder-app h2 { font-size: 26px; } .sbi-fb-srcs-desc { width: 100%; } .sbi-fb-source-list { grid-template-columns: 99%; } .sb-dialog-ctn.sbi-fb-center-boss .sbi-fb-popup-inside { max-width: calc(100% - 40px); } } @media (max-width: 480px) { .sbi-fb-source-ctn .sbi-fb-popup-inside { top: 45px; margin-bottom: 46px; } .sbi-csz-header-insider .sb-button-standard { font-size: 13px; padding: 8px 15px 8px 34px; } .sbi-csz-header-insider .sb-button-standard svg { width: 13px; height: 13px; left: 14px; top: 10px; } .sbi-fb-header.sbi-csz-header { height: 126px; } .sbi-csz-hd-name { height: 30px; margin-top: 5px; } .sb-customizer-ctn .sb-customizer-sidebar { margin-top: 120px; } .sb-fs-boss.sbi-fb-center-boss { overflow: scroll; } .sbi-fb-stp1-elm { flex-wrap: wrap; } .sbi-fb-stp1-elm-txt { margin-right: 0%; width: calc(100% - 50px); } .sbi-fb-stp1-elm .sbi-fb-stp-src-ctn.sbi-fb-stp1-elm-act { margin-left: 24px; } .sbi-fb-stp1-elm .sbi-fb-stp1-elm-act { margin-top: 10px; margin-left: 42px; } } .sb-control-elem-tltp-content{ position: fixed; background: #fff; padding: 8px 11px; text-align: center; line-height: 1.5em; top: 0; left: 0; z-index: 999999999; -webkit-transform: translateX(-50%) translateY(-100%); transform: translateX(-50%) translateY(-100%); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.19); } .sb-control-elem-tltp-content:before{ content: ''; position: absolute; left: 50%; bottom: -10px; border-top: 12px solid #fff; border-right: 12px solid transparent; border-left: 12px solid transparent; -webkit-transform: translateX(-50%); transform: translateX(-50%); z-index: 2; } .sb-control-elem-tltp-content:after{ content: ''; position: absolute; left: 50%; bottom: -12px; margin-left: 0px; border-top: 14px solid #eee; border-right: 15px solid transparent; border-left: 15px solid transparent; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .sb-control-elem-tltp:hover .sb-control-elem-tltp-content{ opacity: 1; visibility: visible; top: 24px; max-width: 300px; width: auto; } .sb-control-elem-tltp-txt{ position: relative; max-width: 300px; width: max-content; } .sb-control-elem-tltp-txt[data-align="left"]{ text-align: left!important; } .sb-tltp-black-link{ text-decoration: underline!important; color: #000; } /* Social Wall Links */ .sb-social-wall-link-wrap { display: flex; font-size: 14px; margin: 10px 0; } .sb-social-wall-link { padding: 0 12px; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link a { text-decoration: none; } .sb-social-wall-link:first-child { padding-left: 0; border-right: 1px solid #ccc; color: #0068A0!important; line-height: 1; } .sb-social-wall-link:last-child { border-right: none; } .sb-social-wall-link a:focus { outline: none; box-shadow: none; } /* Add Source Loading */ .sb-fb-source-redirect-ld{ text-align: center; } .sb-fb-source-redirect-ld div{ display: inline-block; width: 32px; height: 32px; border-radius: 50px; margin: 0 10px; position: relative; background-color: #0096CC; color: #0096CC; -webkit-animation: sb-source-redirect 1s infinite linear alternate; animation: sb-source-redirect 1s infinite linear alternate; -webkit-animation-delay: .5s; animation-delay: .5s; } .sb-fb-source-redirect-ld div:before, .sb-fb-source-redirect-ld div:after{ content: ''; display: inline-block; position: absolute; top: 0; } .sb-fb-source-redirect-ld div:before{ left: -45px; width: 32px; height: 32px; border-radius: 50px; background-color: #0096CC; color: #0096CC; -webkit-animation: sb-source-redirect 1s infinite alternate; animation: sb-source-redirect 1s infinite alternate; -webkit-animation-delay: 0s; animation-delay: 0s; } .sb-fb-source-redirect-ld div:after{ left: 45px; width: 32px; height: 32px; border-radius: 50px; background-color: #0096CC; color: #0096CC; -webkit-animation: sb-source-redirect 1s infinite alternate; animation: sb-source-redirect 1s infinite alternate; -webkit-animation-delay: 1s; animation-delay: 1s; } @-webkit-keyframes sb-source-redirect { 0% {background-color: #0096CC;} 50%,100% {background-color: #B5E5FF;} } @keyframes sb-source-redirect { 0% {background-color: #0096CC;} 50%,100% {background-color: #B5E5FF;} } .sb-fb-source-redirect-info{ text-align: center; margin-top: 50px; } .sb-fb-source-redirect-info strong{ font-size: 18px; } .sb-fb-source-redirect-info p{ color: #8C8F9A; padding: 0 24%; font-size: 16px; margin-bottom: 0px; } .sbi-fb-popup-inside[data-step="redirect_1"]{ width: 575px; height: 320px; display: flex; justify-content: center; align-items: center; } /*Personal Account Popup*/ .sbi-personal-account-ctn .sbi-source-account-box{ display: flex; justify-content: center; align-items: center; } .sbi-pers-account-icon{ width: 64px; height: 64px; display: flex; justify-content: center; align-items: center; border: 7px solid #bfe8ff; border-radius: 50%; box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05), 0px 4px 5px rgba(0, 0, 0, 0.05); } .sbi-pers-account-icon svg{ float: left; } .sbi-personal-account-ctn .sbi-fb-personal-step1 .sbi-fb-source-top { padding: 27px 54px 27px; text-align: center; } .sbi-fb-personal-step2 .sbi-fb-source-btn{ margin-right: 0px !important; } .sbi-personal-account-ctn button{ font-weight: 600; } .sbi-fb-personal-form{ text-align: left; padding-top: 25px; padding-bottom: 20px; } .sbi-fb-personal-step2 > *{ padding-left: 19px; padding-right: 19px; } .sbi-fb-personal-upload-btn{ margin-top: 12px; } .sbi-fb-personal-upload-btn button span{ padding: 0 5px; } .sbi-fb-personal-upload-btn button svg{ float: left; } .sbi-fb-personal-upload-btn input[type="file"]{ display: none; } .sbi-fb-personal-upload-btn > *{ display: inline-flex; margin-right: 7px!important; } .sbi-fb-personal-textarea{ margin-top: 16px; } .sbi-fb-personal-textarea > *{ width: 100%; float: left; } .sbi-fb-personal-textarea label{ font-size: 14px; color: #434960; margin-bottom: 10px; margin-top: 10px; } .sbi-fb-personal-textarea textarea{ height: 77px; border: 1px solid #D0D1D7; border-radius: 1px; padding: 8px 2px 2px 12px; outline: none; } /*** 7.0 Settings CTA ***/ .sbi-settings-cta { background-color: #fff; padding: 24px 20px 20px; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); margin-top: 12px; } .sbi-settings-cta .sbi-cta-title, .sbi-settings-cta .sbi-cta-head-inner { display: flex; } .sbi-settings-cta .sbi-cta-head-inner { justify-content: space-between; max-width: 820px; } .sbi-settings-cta .sbi-cta-head-inner .sbi-cta-btn a { display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 7px 12px 8px 20px; font-weight: 600; font-size: 14px; line-height: 160%; margin-top: 10px; } .sbi-settings-cta .sbi-cta-head-inner .sbi-cta-btn a svg { margin-left: 12px; width: 10px; } .sbi-settings-cta .sbi-plugin-title-bt { display: flex; } .sbi-settings-cta .sbi-plugin-title-bt .sbi-cta-btn { width: 177px; } .sbi-settings-cta .sbi-cta-title .sbi-plugin-logo { background: #FFFFFF; box-shadow: 0px 6.05242px 7.56552px rgba(0, 26, 119, 0.0415), 0px 3.39293px 4.24117px rgba(0, 26, 119, 0.04), 0px 1.80196px 2.25245px rgba(0, 26, 119, 0.0285), 0px 0.749837px 0.937296px rgba(0, 26, 119, 0.0337); border-radius: 2px; min-width: 60px; width: 65px; height: 65px; display: flex; justify-content: center; align-items: center; margin-right: 30px; border: 1px solid #ecebeb; } #sbi-builder-app .sbi-settings-cta .sbi-cta-title .sbi-plugin-logo{ width: 75px; height: 75px; } .sbi-settings-cta .sbi-cta-title .sbi-cta-discount-label { background: #FFEFCC; border-radius: 2px; padding: 4px 14px 4px 12px; font-weight: 600; font-size: 14px; line-height: 160%; color: #663D00; display: flex; flex-direction: row; justify-content: space-between; align-items: center; max-width: 505px; margin-top: 10px; box-sizing: border-box; margin-right: 10px; } #sbi-builder-app .sbi-settings-cta .sbi-cta-title .sbi-cta-discount-label { max-width: 250px; } #sbi-builder-app .sbi-settings-cta .sbi-cta-title .sbi-cta-discount-label svg { margin-right: 6px; } .sbi-settings-cta .sbi-cta-title .sbi-cta-discount-label svg path{ fill: #663D00; } #sbi-builder-app .sbi-settings-cta .sbi-cta-title .sbi-cta-discount-label { color: #663D00; background: #FFEFCC; } .sbi-settings-cta .sbi-cta-boxes { margin: 36px 0px 0px 7px; display: flex; background-color: #fff; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); border: 1px solid #E8E8EB; border-bottom: 0px solid transparent; max-width: 1170px; } .sbi-settings-cta .sbi-cta-box:not(:last-child) { border-right: 1px solid #E8E8EB; } .sbi-settings-cta .sbi-cta-box { padding: 16px 30px 16px 18px; display: flex; } .sbi-settings-cta .sbi-cta-box .sbi-cta-box-icon { margin-right: 24px; max-height: 50px; } .sbi-settings-cta .sbi-cta-box .sbi-cta-box-title { font-weight: 600; font-size: 14px; line-height: 140%; padding-top: 5px; } .sbi-settings-cta .sbi-cta-much-more{ display: flex; padding: 0 14px; flex-wrap: wrap; margin-top: 3px; justify-content: space-between; max-width: 1170px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-left { width: 330px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul { display: grid; grid-template-columns: 33% 33% 33%; grid-column-gap: 2%; padding-top: 10px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-left h4 { font-weight: 600; font-size: 18px; line-height: 140%; color: #141B38; margin: 1.33em 0 !important; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul li { font-size: 14px; line-height: 160%; color: #434960; width: 260px; position: relative; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul li::before { background: #0096CC; width: 4px; height: 4px; content: ''; position: absolute; left: -19px; top: 10px; } .sbi-settings-cta .sbi-cta-try-demo { margin-top: 13px; max-width: 1180px; } .sbi-settings-cta .sbi-cta-try-demo a { width: 100%; justify-content: center; display: flex; align-items: center; vertical-align: middle; background: #F3F4F5; border: 1px solid #DCDDE1; box-sizing: border-box; border-radius: 2px; padding: 7px 20px; font-weight: 600; font-size: 14px; line-height: 22px; color: #141B38; box-sizing: border-box; letter-spacing: 0.2px; cursor: pointer; transition: all 0.15s ease-in-out; text-decoration: none; } .sbi-settings-cta .sbi-cta-try-demo a span svg { transform: translate(5px, 4px); } .sbi-settings-cta .sbi-cta-try-demo .sbi-btn span { margin-left: 9px; transform: translateY(1px); } .sbi-cta-toggle-features { background: #F3F4F5; width: 100%; display: flex; justify-content: left; padding: 5px 0 4px 15px; box-shadow: 0px 1px 2px rgb(0 0 0 / 5%), 0px 4px 5px rgb(0 0 0 / 5%); box-sizing: border-box; } .sbi-cta-toggle-features .sbi-cta-toggle-btn { font-weight: 600; font-size: 14px; line-height: 160%; border: none; background: none; display: flex; cursor: pointer; } .sbi-cta-toggle-features .sbi-cta-toggle-btn svg { transform: translateY(0px); margin-left: 4px; } @media (min-width: 1170px) and (max-width: 1540px) { .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul li { width: 240px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-left { width: 220px; } } @media (min-width: 1170px) and (max-width: 1340px) { .sbi-settings-cta .sbi-cta-box .sbi-cta-box-icon { margin-right: 15px; } .sbi-settings-cta .sbi-cta-box { padding: 16px 15px 16px 15px; } } @media (max-width: 1300px) { .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul { grid-template-columns: 48% 48%; } } @media (max-width: 1170px) { .sbi-settings-cta .sbi-cta-boxes { flex-wrap: wrap; } .sbi-settings-cta .sbi-cta-boxes .sbi-cta-box { width: 50%; box-sizing: border-box; } .sbi-settings-cta .sbi-cta-box:not(:last-child) { border-right: none; } .sbi-settings-cta .sbi-cta-box:first-child, .sbi-settings-cta .sbi-cta-box:nth-child(2) { border-bottom: 1px solid #E8E8EB; } .sbi-settings-cta .sbi-cta-box:first-child, .sbi-settings-cta .sbi-cta-box:nth-child(3) { border-right: 1px solid #E8E8EB; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right { padding-left: 20px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul { margin: 0; padding: 0; } } @media (max-width: 770px) { .sbi-settings-cta .sbi-cta-boxes .sbi-cta-box { width: 100%; align-items: center; } .sbi-settings-cta .sbi-cta-box { border: none; } .sbi-settings-cta .sbi-cta-box:not(:last-child) { border-bottom: 1px solid #E8E8EB; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-right ul { grid-template-columns: 100%; margin-top: 0px; } .sbi-settings-cta .sbi-cta-much-more .sbi-cta-mm-left h4 { margin-bottom: 10px !important; } .sb-tab-content .sb-tab-box .sbi-caching-pro-cta { padding: 8px 25px; } .sbi-settings-cta .sbi-cta-head-inner { flex-wrap: wrap; } .sbi-settings-cta .sbi-cta-title { margin-bottom: 20px; } .sbi-settings-cta .sbi-cta-btn { width: 100%; } .sbi-settings-cta .sbi-plugin-title-bt { flex-direction: column; } .sbi-plugin-title { width: 67%; } } @media (max-width: 580px) { .sbi-settings-cta .sbi-cta-title .sbi-plugin-logo { margin-right: 20px; } } /* Uncanny Automator Integration Popup */ .sbi-integration-popup-modal .sbi-integration-popup { width: 100%; max-width: 580px; box-shadow: 0px 26.7377px 77.2886px rgba(0, 0, 0, 0.107828), 0px 14.2952px 41.3222px rgba(0, 0, 0, 0.0894161), 0px 8.01379px 23.1649px rgba(0, 0, 0, 0.075), 0px 4.25607px 12.3027px rgba(0, 0, 0, 0.0605839), 0px 1.77104px 5.11942px rgba(0, 0, 0, 0.0421718); border-radius: 8px; padding: 25px 0 0 0; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-content-header { text-align: center; padding: 0 100px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-content-header img { width: 226px; margin-bottom: -55px; } #sbi-settings .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-content-header h3 { font-weight: 600; font-size: 18px; line-height: 140%; text-align: center; color: #141B38; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-content-header p { font-weight: 400; font-size: 12px; line-height: 160%; text-align: center; color: #696D80; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-steps { margin-top: 16px; padding: 33px 43px 48px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step { background: #FFFFFF; border: 1px solid #E6E6EB; border-radius: 8px; padding: 21px 100px 27px 20px; position: relative; margin-bottom: 12px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-step-image { position: absolute; right: -7px; width: 170px; top: 17px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-setup-step .sbi-step-image { width: 186px; right: -1px; top: 8px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step h4 { font-weight: 600; font-size: 14px; line-height: 160%; color: #141B38; margin: 0; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step p { font-weight: 400; font-size: 12px; line-height: 160%; color: #696D80; margin-top: 0px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn { margin-top: 16px; border-radius: 4px; padding: 6px 8px; font-weight: 600; font-size: 12px; line-height: 160%; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn-install { background-color: #0068A0; color: #fff; box-shadow: 0px 2px 5px rgba(60, 66, 87, 0.12), 0px 1px 1px rgba(0, 0, 0, 0.08), inset 0px -1px 1px rgba(0, 0, 0, 0.12); transition: all .2s ease-in; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn-install:hover { background-color: #117db7; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn-install:disabled { background-color: #117db7 !important; color: white !important; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn svg { margin-right: 1px; width: 16px; height: 17px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn svg path { fill: white; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step .sbi-btn:disabled { background: #F9F9FA; color: #696D80; } @media (max-width: 768px) { .sbi-integration-popup-modal .sbi-integration-popup { width: calc(85% - 20px); left: 0px; } } @media (max-width: 600px) { .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-content-header { padding: 0 50px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-steps { padding: 33px 25px 48px; } .sbi-integration-popup-modal .sbi-integration-popup .sbi-popup-ua-integration-step { padding: 21px 94px 27px 20px; } } admin/builder/assets/css/preview.css000064400000105010150515074570013555 0ustar00body{ overflow-x:hidden; } .sbi-preview-ctn .no-overflow{ overflow: hidden!important; } .sbi-preview-ctn .sbi-fb-fs{ width: 100%; position: relative; float: left; box-sizing: border-box; } .sbi-fullsize-link{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; z-index: 9; cursor: pointer; } .sbi-feed-height{ overflow-x: hidden!important; } .sbi-preview-ctn h1, .sbi-preview-ctn h2, .sbi-preview-ctn h3, .sbi-preview-ctn h4, .sbi-preview-ctn h5, .sbi-preview-ctn h6{ padding: 0px; margin: 0px; line-height: 1em; } .sbi-preview-ctn h3, .sbi-preview-ctn h4, .sbi-preview-ctn h5, .sbi-preview-ctn h6, .sbi-preview-ctn p { float: left; width: 100%; clear: both; padding: 0; margin: 5px 0; line-height: 1.4; word-wrap: break-word; } /*Preview Sections Highlights*/ .sbi-preview-section{ opacity: 1; } .sbi-preview-section[data-dimmed="true"]{ opacity: 0.4; } .sbi-preview-ctn .sbi-preview-header-visual{ margin-bottom: 25px; } .sbi-preview-ctn .sbi-preview-header-cover{ overflow: hidden; height: 300px; } .sbi-preview-ctn .sbi-preview-header-cover img{ position: absolute; width: 100%; height: auto; left: 0px; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); } .sbi-preview-ctn .sbi-preview-header-likebox{ position: absolute; right: 10px; bottom: 10px; display: flex; align-items: center; justify-content: center; background: #eee; border-radius: 2px; padding: 3px 5px; color: #445790; } .sbi-preview-ctn .sbi-preview-header-likebox svg{ fill: currentColor; width: 18px; margin-right: 5px; float: left; } .sbi-preview-ctn .sbi-preview-header-likebox span{ font-size: 15px; line-height: 20px; } .sbi-preview-ctn .sbi-preview-header-info-ctn{ padding: 0 20px; } .sbi-preview-ctn .sbi-preview-header-avatar{ width: 100px; border-color: 3px; border: 2px solid #fff; margin-top: -25px; border-radius: 3px; position: absolute; left: 20px; } .sbi-preview-ctn .sbi-preview-header-avatar img{ width: 100%; border-radius: 3px; float: left; } .sbi-preview-ctn .sbi-preview-header-info{ padding-top: 10px; margin-left: 125px; } .sbi-preview-ctn .sbi-preview-header-text-h{ display: flex; align-items: center; line-height: 1em } .sbi-preview-ctn .sbi-header-text{ line-height: 1em!important; } .sbi-preview-ctn .sbi-preview-header-text-icon{ margin-right: 10px; } .sbi-preview-ctn .sbi-preview-header-text-icon svg{ float: left; } .sbi-preview-ctn .sbi-preview-header-name { display: inline-block; margin: 0 8px 0 0; padding: 0; font-size: 1.2em; line-height: 1.2em; } .sbi-preview-ctn .sbi-preview-header-bio{ margin: 3px 0 0 0; padding: 0; line-height: 1.2em; } /*Load More Button*/ .sbi-preview-ctn .sbi-preview-loadmore-ctn{ margin-bottom: 20px; } .sbi-preview-ctn .sbi-preview-loadmore-btn{ display: flex; justify-content: center; align-items: center; cursor: pointer; min-height: 45px; padding: 5px 0; margin: 10px 0 0 0; line-height: 1em; font-size: 15px; border: none; background: #eee; background: rgba(0,0,0,0.05); width: 100%; position: relative; text-align: center; box-sizing: border-box; outline: none; text-decoration: none; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; -moz-transition: background 0.1s ease-in-out; -webkit-transition: background 0.1s ease-in-out; -o-transition: background 0.1s ease-in-out; transition: background 0.1s ease-in-out; } .sbi-preview-ctn .sbi-preview-loadmore-btn:hover { background: #ddd; background: rgba(0,0,0,0.1); text-decoration: none; -moz-transition: background 0.1s ease-in-out; -webkit-transition: background 0.1s ease-in-out; -o-transition: background 0.1s ease-in-out; transition: background 0.1s ease-in-out; } /*Post List Layout*/ /* Masonry Layout */ /* [data-feed-layout="masonry"] .sbi-post-item-ctn{ margin: 0px!important; } [data-feed-layout="masonry"]{ display: grid; grid-gap: 20px; grid-auto-rows: 0; } [data-feed-layout="masonry"][data-feed-columns="1"]{ grid-template-columns: repeat(1, minmax(100px,1fr)); } [data-feed-layout="masonry"][data-feed-columns="2"]{ grid-template-columns: repeat(2, minmax(100px,1fr)); } [data-feed-layout="masonry"][data-feed-columns="3"]{ grid-template-columns: repeat(3, minmax(100px,1fr)); } [data-feed-layout="masonry"][data-feed-columns="4"]{ grid-template-columns: repeat(4, minmax(100px,1fr)); } [data-feed-layout="masonry"][data-feed-columns="5"]{ grid-template-columns: repeat(5, minmax(100px,1fr)); } [data-feed-layout="masonry"][data-feed-columns="6"]{ grid-template-columns: repeat(6, minmax(100px,1fr)); } */ [data-feed-layout="masonry"] .sbi-post-item-ctn{ height: auto!important; } [data-feed-layout="masonry"][data-feed-columns="1"] .sbi-post-item-ctn{ width: 100%; } [data-feed-layout="masonry"][data-feed-columns="2"] .sbi-post-item-ctn{ width: 47%; margin: 8px 1.5%; } [data-feed-layout="masonry"][data-feed-columns="3"] .sbi-post-item-ctn{ width: 30.33%; margin: 8px 1.5%; } [data-feed-layout="masonry"][data-feed-columns="4"] .sbi-post-item-ctn{ width: 22%; margin: 8px 1.5%; } [data-feed-layout="masonry"][data-feed-columns="5"] .sbi-post-item-ctn{ width: 17%; margin: 8px 1.5%; } [data-feed-layout="masonry"][data-feed-columns="6"] .sbi-post-item-ctn{ width: 13.516%; margin: 8px 1.5%; } [data-feed-layout="masonry"] .sbi-media-item-ctn .sbi-media-item-image-real{ height: 100%; position: absolute; width: 100%; left: 0; top: 0; bottom: 0; right: 0; } [data-feed-layout="masonry"] .sbi-media-item-ctn .sbi-media-item-image-poster{ opacity: 0; } /* Grid Layout */ [data-feed-layout="grid"]{ display: grid; grid-gap: 20px; } [data-feed-layout="grid"][data-feed-columns="1"]{ grid-template-columns: repeat(1, minmax(100px,1fr)); } [data-feed-layout="grid"][data-feed-columns="2"]{ grid-template-columns: 1fr 1fr; } [data-feed-layout="grid"][data-feed-columns="3"]{ grid-template-columns: repeat(3, minmax(100px,1fr)); } [data-feed-layout="grid"][data-feed-columns="4"]{ grid-template-columns: repeat(4, minmax(100px,1fr)); } [data-feed-layout="grid"][data-feed-columns="5"]{ grid-template-columns: repeat(5, minmax(100px,1fr)); } [data-feed-layout="grid"][data-feed-columns="6"]{ grid-template-columns: repeat(6, minmax(100px,1fr)); } [data-feed-layout="grid"] .sbi-post-item-ctn{ overflow: hidden; margin: 0px!important } [data-feed-layout="grid"] .sbi-post-item-ctn .sbi-post-grid-image{ position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; bottom: 0px; right: 0px; background-size: cover !important; background-position: center center !important; } [data-feed-layout="grid"] .sbi-photos-item-ctn img{ opacity: 0 } [data-feed-layout="grid"] .sbi-singlemedia-item.sbi-albums-item-ctn .sbi-albums-item-cover{ height: calc(100% - 70px); left: 0; top: 0; right: 0; } [data-feed-layout="grid"] .sbi-albums-item-ctn .sbi-post-item-content{ height: inherit; } .sbi-preview-ctn .sbi-media-item-ctn{ background: none!important; } .sbi-preview-ctn .sbi-singlemedia-item{ background: none!important; padding: 0px!important } [data-feed-layout="list"] .sbi-post-item-ctn{ height: auto!important; } /*Post Single Item*/ .sbi-post-item-info-ctn{ display: flex; align-items: center; margin-bottom: 15px; padding: 0; line-height: 1.2; width: 100%; } .sbi-post-item-info{ float: left; padding: 3px 0 0 0; font-size: 14px; font-weight: bold; line-height: 1.2; } .sbi-post-item-date{ color: #9197a3; font-weight: normal; font-size: 11px; margin-top: 1px !important; margin-bottom: 0px !important; } .sbi-post-item-avatar, .sbi-post-item-avatar img{ width: 45px; height: 45px; border-radius: 50px; } .sbi-post-item-avatar{ margin-right: 10px; } .sbi-post-item-author-name{ font-weight: bold; } .sbi-post-item-story{ font-weight: normal; font-size: 14px; padding: 3px 0 0 0; line-height: 1.2; } .sbi-preview-ctn .sbi-post-item-ctn{ width: 100%; float: left; position: relative; box-sizing: border-box; padding: 15px; margin: 8px 0; } .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="half"] .sbi-post-item-sides, .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn{ display: grid!important; grid-template-columns: calc(50% - 15px) calc(50% - 15px); grid-column-gap: 30px; } .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="half"][data-post-type="links"] .sbi-post-item-sides{ display: flex; flex-direction: column-reverse; } .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="thumb"] .sbi-post-item-sides, .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn{ display: grid; grid-template-columns: calc(20% - 15px) calc(80% - 15px); grid-column-gap: 30px; } .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-sides{ display: flex; flex-direction: column-reverse; } /* Added for events */ .sbi-preview-ctn .sbi-preview-posts-list-ctn[data-feed-type="events"] .sbi-post-item-ctn[data-post-layout="half"] .sbi-post-item-sides, .sbi-preview-ctn .sbi-preview-posts-list-ctn[data-feed-type="events"] .sbi-post-item-ctn[data-post-layout="thumb"] .sbi-post-item-sides{ display: grid!important; } [data-feed-type="reviews"] [data-post-layout="half"] .sbi-post-item-sides, [data-feed-type="reviews"] [data-post-layout="thumb"] .sbi-post-item-sides{ grid-template-columns: 100%!important; } .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="half"][data-post-type="statuses"] .sbi-post-item-sides, .sbi-preview-ctn .sbi-post-item-ctn[data-post-layout="thumb"][data-post-type="statuses"] .sbi-post-item-sides{ display: block!important; width: 100%!important; } .sbi-preview-ctn .sbi-preview-posts-list-ctn[data-boxshadow="true"] .sbi-post-item-ctn{ box-shadow: 0 0 10px 0 rgba(0,0,0, 0.15); } .sbi-preview-ctn .sbi-preview-posts-list-ctn[data-poststyle="regular"] .sbi-post-item-ctn{ padding: 15px 0px; } .sbi-preview-ctn [data-feed-layout="carousel"][data-feed-type="singlealbum"] .sbi-post-item-ctn{ height: 100%; background-position: center!important; background-size: cover!important; } /*Narrow Rules for Preview*/ [data-preview-device="mobile"] [data-narrow="active"] [data-post-layout="half"] .sbi-post-item-sides, [data-preview-device="mobile"] [data-narrow="active"] [data-post-layout="thumb"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="3"] [data-post-layout="half"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="3"] [data-post-layout="thumb"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="4"] [data-post-layout="half"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="4"] [data-post-layout="thumb"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="5"] [data-post-layout="half"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="5"] [data-post-layout="thumb"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="6"] [data-post-layout="half"] .sbi-post-item-sides, [data-narrow="active"][data-feed-columns="6"] [data-post-layout="thumb"] .sbi-post-item-sides, [data-preview-device="mobile"] [data-narrow="active"] [data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn, [data-preview-device="mobile"] [data-narrow="active"] [data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn{ display: flex !important; flex-direction: column-reverse; } [data-narrow="active"][data-feed-columns="3"] [data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="3"] [data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="4"] [data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="4"] [data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="5"] [data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="5"] [data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="6"] [data-post-layout="half"][data-post-type="links"] .sbi-post-item-link-ctn, [data-narrow="active"][data-feed-columns="6"] [data-post-layout="thumb"][data-post-type="links"] .sbi-post-item-link-ctn{ display: flex !important; flex-direction: column; } .sbi-preview-ctn .sbi-post-item-text{ padding: 0; margin: 5px 0; line-height: 1.4; word-wrap: break-word; } .sbi-preview-ctn .sbi-post-item-text a:hover{ text-decoration: underline; } .sbi-post-item-text-expand a{ font-size: 11px; font-weight: normal; cursor: pointer; } .sbi-preview-ctn .sbi-post-item-text-expand a:hover{ text-decoration: underline; } .sbi-preview-ctn .sbi-post-item-meta-top{ display: flex; align-items: center; } .sbi-preview-ctn .sbi-post-item-action-link{ margin-left: auto; } .sbi-preview-ctn .sbi-post-item-action-txt{ font-size: 11px; cursor: pointer; font-weight: normal; } .sbi-preview-ctn .sbi-post-item-action-link a:hover{ text-decoration: underline; } .sbi-preview-ctn .sbi-post-item-dot{ padding: 0 5px; } .sbi-preview-ctn .sbi-post-item-share-link{ position: relative; } .sbi-preview-ctn .sbi-post-item-share-tooltip{ position: absolute; bottom: 22px; right: -5px; width: 100px; padding: 3px 5px; margin: 0; background: #333; color: #fff; font-size: 12px; line-height: 1.4; display: flex; align-items: center; justify-content: center; z-index: 9999; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .sbi-preview-ctn .sbi-post-item-share-tooltip:before{ content: ''; position: absolute; right: 11px; bottom: -4px; border-top: 7px solid #333; border-left: 7px solid transparent; border-right: 7px solid transparent; } .sbi-preview-ctn .sbi-post-item-share-tooltip a{ display: flex; width: 26px; height: 26px; justify-content: center; align-items: center; color: #fff !important; -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } .sbi-preview-ctn .sbi-post-item-share-tooltip svg{ width: 16px; } .sbi-preview-ctn .sbi-post-item-meta{ height: 37px; margin: 5px 12px 5px 0; display: flex; padding: 0 5px 0 10px; justify-content: center; align-items: center; cursor: pointer; border-radius: 4px; background: rgba(0,0,0,0.05); box-shadow: 0 0 0 1px rgba(0,0,0,0.07); -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-preview-ctn .sbi-post-item-meta:hover{ box-shadow: 0 0 0 1px rgb(0 0 0 / 9%); background: rgba(0,0,0,0.07); } .sbi-preview-ctn .sbi-post-item-view-comment,.sbi-post-meta-item{ display: flex; justify-content: center; align-items: center; } .sbi-preview-ctn .sbi-post-meta-item{ float: left; width: auto; display: block; list-style-type: none !important; margin: 0 10px 0 0 !important; padding: 0 !important; font-size: 11px; line-height: 16px !important; background: none !important; } .sbi-preview-ctn .sbi-post-meta-item-icon, .sbi-post-meta-item-icon svg{ width: 16px; position: relative; float: left; z-index: 2; } .sbi-preview-ctn .sbi-post-meta-item-icon{ margin-right: 5px; } .sbi-preview-ctn .sbi-post-meta-item-icon svg:nth-of-type(2){ position: absolute; left: 0px; top: 0px; z-index: -1; } .sbi-preview-ctn .sbi-post-item-full-img{ position: relative; float: left; width: 100%; height: auto; } /*Responsive Meta & Actions Links*/ .sbi-preview-ctn [data-feed-columns="3"] .sbi-post-item-meta-top, .sbi-preview-ctn [data-feed-columns="4"] .sbi-post-item-meta-top, .sbi-preview-ctn [data-feed-columns="5"] .sbi-post-item-meta-top, .sbi-preview-ctn [data-feed-columns="6"] .sbi-post-item-meta-top{ flex-direction: column-reverse; align-items: flex-start; } .sbi-preview-ctn [data-feed-columns="3"] .sbi-post-item-action-link, .sbi-preview-ctn [data-feed-columns="4"] .sbi-post-item-action-link, .sbi-preview-ctn [data-feed-columns="5"] .sbi-post-item-action-link, .sbi-preview-ctn [data-feed-columns="6"] .sbi-post-item-action-link{ margin-left: unset; } /*Light & Auto Icon Theme*/ .sbi-post-meta-item-icon-comment svg path, .sbi-post-meta-item-icon-share svg path, .sbi-post-meta-item-icon-like svg path{ fill: rgba(0,0,0,0.4); -webkit-transition: all 0.2s ease; transition: all 0.2s ease; } .sbi-post-meta-item-icon-comment svg.sbi-svg-bg path, .sbi-post-meta-item-icon-share svg.sbi-svg-bg path{ fill: rgba(255,255,255,0.7); } .sbi-post-meta-item-icon-like svg.sbi-svg-bg path{ fill: url(#likeGrad); } .sbi-preview-ctn .sbi-post-item-meta:hover svg path{ fill: rgba(0,0,0,0.5); } .sbi-preview-ctn .sbi-post-item-meta:hover .sbi-post-meta-item-icon-share svg.sbi-svg-bg path{ fill: #fdf3d0; } .sbi-preview-ctn .sbi-post-item-meta:hover .sbi-post-meta-item-icon-comment svg.sbi-svg-bg path{ fill: #fff; } .sbi-preview-ctn .sbi-post-item-meta:hover .sbi-post-meta-item-icon-like svg.sbi-svg-bg path{ fill: url(#likeGradHover); } /*Dark Icon Theme*/ .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-comment svg path, .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-share svg path, .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-like svg path{ fill: rgba(255,255,255,0.05); -webkit-transition: all 0.2s ease; transition: all 0.2s ease; } .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-comment svg.sbi-svg-bg path, .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-share svg.sbi-svg-bg path{ fill: rgba(255,255,255,0.9); } .sbi-post-item-meta[data-icon-theme="dark"] .sbi-post-meta-item-icon-like svg.sbi-svg-bg path{ fill: url(#likeGradDark); } .sbi-preview-ctn .sbi-post-item-meta[data-icon-theme="dark"]:hover svg path{ fill: #fff; } .sbi-preview-ctn .sbi-post-item-meta[data-icon-theme="dark"]:hover .sbi-post-meta-item-icon-share svg.sbi-svg-bg path{ fill: #fdf3d0; } .sbi-preview-ctn .sbi-post-item-meta[data-icon-theme="dark"]:hover .sbi-post-meta-item-icon-comment svg.sbi-svg-bg path{ fill: #fff; } .sbi-preview-ctn .sbi-post-item-meta[data-icon-theme="dark"]:hover .sbi-post-meta-item-icon-like svg.sbi-svg-bg path{ fill: url(#likeGradHover); } .sbi-preview-ctn .sbi-post-item-meta[data-icon-theme="dark"]:hover svg.sbi-svg-bg{ z-index: 3!important; } /*Post Meta comments*/ .sbi-post-item-meta-comments p, .sbi-post-item-meta-comments .sbi-post-comment-item, .sbi-post-item-meta-comments .sbi-comment-reply, .sbi-post-item-meta-comments .sbi-post-comment-item p { width: 100%; min-width: 100%; font-size: 12px; margin: 0 0 1px 0; line-height: 17px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .sbi-post-item-comments-top{ font-size: 12px; margin-bottom: 1px; padding: 10px 10px; background: rgba(0,0,0,0.05); border-radius: 4px; border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; } .sbi-post-item-comments-top a:hover{ text-decoration: underline; } .sbi-post-item-comments-icon{ width: 16px; height: 16px; float: left; margin-right: 8px; display: flex; justify-content: center; align-items: center; } .sbi-post-item-comments-icon svg{ width: 14px; margin-top: 4px; } .sbi-post-item-comments-list{ background: rgba(0,0,0,0.05); border-radius: 4px; border-top-left-radius: 0px; border-top-right-radius: 0px; } .sbi-post-comment-item{ padding: 7px 10px; font-size: 12px; display: flex; align-items: flex-start; } .sbi-post-comment-item-avatar{ width: 32px; height: 32px; float: left; margin-right: 10px; margin-top: 3px; } .sbi-post-comment-item-avatar img{ width: 32px; height: 32px; float: left; border-radius: 50px; } .sbi-post-comment-item-author{ font-weight: bold; margin-right: 6px; float: left; } .sbi-post-comment-item-author:hover{ text-decoration: underline; } .sbi-post-comment-item-txt{ font-size: 12px; line-height: 1.4; margin: 0px; } .sbi-post-comment-item-date{ font-size: 11px; margin: 3px 0 0 0; display: block; font-style: italic; line-height: 1em; clear: both; float: left; } .sbi-post-item-media-album, .sbi-post-item-media-album a,.sbi-post-item-album-poster{ float: left; width: 100%; position: relative; display: block; } .sbi-post-item-album-thumb{ position: relative; display: inline-block; background-size: cover; background-position: center center; background-repeat: no-repeat; } .sbi-post-item-album-thumb-overlay{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; z-index: 3; background: rgba(0,0,0,0.4); display: flex; justify-content: center; align-items: center; color: #fff; font-size: 30px; } .sbi-post-item-album-thumbs{ width: 100%; display: grid; margin-top: 5px; float: left; } .sbi-post-item-album-thumbs[data-length='1']{ grid-template-columns: 100%; } .sbi-post-item-album-thumbs[data-length='2']{ grid-template-columns: calc(50% - 3px) calc(50% - 3px); grid-column-gap: 5px; } .sbi-post-item-album-thumbs[data-length='3']{ grid-template-columns: calc(33.33% - 3px) calc(33.33% - 3px) calc(33.33% - 3px); grid-column-gap: 5px; } .sbi-post-item-album-thumbs .sbi-post-item-album-thumb:first-of-type{ grid-row: 1 / 1; grid-column: 1 / 1; padding-bottom: 100%; } .sbi-post-item-media-album{ margin-bottom: 10px; } .sbi-preview-ctn .sbi-post-item-iframe-ctn[data-source="spotify"] iframe{ width: 100%; height: 80px; } .sbi-preview-ctn .sbi-post-item-iframe-ctn[data-source="soundcloud"] iframe{ width: 100%; height: 100px; } .sbi-preview-ctn .sbi-post-item-media-ctn{ margin: 5px 0px; } .sbi-preview-ctn .sbi-post-item-video-ctn{ position: relative; } .sbi-preview-ctn .sbi-post-item-iframe-ctn[data-source="video"] .sbi-post-item-iframe, /*.sbi-preview-ctn .sbi-post-item-video-ctn,*/ .sbi-preview-ctn .sbi-videos-item-ctn .sbi-videos-item-source{ width: 100%; float: left; clear: both; /*margin: 5px 0;*/ position: relative; /*padding-bottom: 62%;*/ padding-bottom: 56.25%; } .sbi-play-video-icon{ position: absolute; width: 56px; height: 56px; background: rgba(0,0,0,0.7); color: #fff; left: 50%; top: 50%; border-radius: 8px; cursor: pointer; z-index: 1; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } .sbi-play-video-icon:before{ content: ''; position: absolute; border-left: 22px solid currentColor; border-top: 17px solid transparent; border-bottom: 17px solid transparent; left: 19px; top: 11px; border-radius: 4px; } .sbi-preview-ctn .sbi-post-item-iframe-ctn[data-source="video"] .sbi-post-item-iframe iframe, .sbi-preview-ctn .sbi-post-item-video-ctn[data-lightbox="false"] iframe, .sbi-preview-ctn .sbi-videos-item-ctn[data-lightbox="false"] .sbi-videos-item-source iframe, .sbi-lightbox-video iframe, .sbi-preview-ctn .sbi-videos-item-source iframe{ position: absolute; width: 100%; height: 100%; z-index: 1; top: 0; left: 0; margin: 0; padding: 0; border: 0; } .sbi-lightbox-video { width: 950px; background: #212121; float: left; clear: both; padding-bottom: 56.25%; position: relative; } .sbi-preview-ctn .sbi-post-item-video-ctn iframe{ width: 100%; float: left; } .sbi-preview-ctn .sbi-post-item-link-ctn{ width: 100%; float: left; clear: both; padding: 8px; margin: 10px 0 5px 0; background: rgba(0,0,0,0.02); border: 1px solid rgba(0,0,0,0.07); box-sizing: border-box; } .sbi-preview-ctn .sbi-post-item-link-ctn[data-linkbox="on"]{ border: 0px !important; background: none !important; padding: 0px !important; } .sbi-preview-ctn .sbi-post-item-link-a:hover{ text-decoration: underline; } .sbi-preview-ctn .sbi-post-item-link-ctn img{ width: 100%; max-width: 100%; height: auto; float: none; } .sbi-preview-ctn .sbi-post-item-link-ctn > a{ width: 100%; max-width: 100%; margin-right: 0%; margin-bottom: 5px; text-align: center; float: left; } .sbi-preview-ctn .sbi-post-item-link-info{ line-height: 1.4; } .sbi-preview-ctn .sbi-photos-item-ctn{ margin: 0 0 20px 0; padding: 0; text-align: center; border: 1px solid rgba(0, 0, 0, .1); } [data-feed-layout="grid"] .sbi-photos-item-ctn, [data-feed-layout="grid"] .sbi-albums-item-ctn{ border-radius: unset!important; } .sbi-preview-ctn .sbi-singlemedia-item-info{ display: flex; flex-direction: column; align-items: center; } .sbi-preview-ctn .sbi-singlemedia-item-info a:hover{ text-decoration: underline; } .sbi-preview-ctn .sbi-singlemedia-item-info{ width: 100%; height: 70px; float: left; clear: both; overflow: hidden; } .sbi-preview-ctn .sbi-singlemedia-item-info > h4{ font-size: 14px!important; line-height: 1.2!important; margin: 10px 0 0 0!important; padding: 0!important; } .sbi-preview-ctn .sbi-singlemedia-item-info > p{ font-size: 12px; color: gray; margin: 5px 0 0 0; } .sbi-preview-ctn .sbi-singlemedia-item{ margin: 0 0 20px 0; text-align: center; } .sbi-preview-ctn .sbi-preview-likebox-ctn iframe{ width: 100% !important; margin: 0 !important; border: 0 !important; padding: 0; position: relative; top: 0; left: 0; } /*Event Details*/ .sbi-preview-ctn .sbi-post-event-street{ display: block } /* Featured & Single Album Holder */ .sbi-preview-ctn .sbi-single-holder-ctn{ height: 600px; background: #fff; box-shadow: 0 0px 6px rgba(0,0,0,0.05); display: flex; justify-content: center; align-items: center; flex-direction: column; } .sbi-preview-ctn .sbi-single-holder-img{ width: 130px; height: 130px; background: #F3F4F5; border: 1px dashed #D0D1D7; display: flex; justify-content: center; align-items: center; margin-bottom: 50px; } .sbi-preview-ctn .sbi-single-holder-content{ text-align: center; } .sbi-preview-ctn .sbi-single-holder-content strong{ font-size: 24px; margin-bottom: 10px; } .sbi-preview-ctn .sbi-single-holder-content p{ font-size: 16px; line-height: 1.7em; color: #8C8F9A; margin: 0px; margin-top: 8px; } /*Post Element Overlay */ .sbi-preview-ctn .sbi-post-overlay{ position: absolute; width: 100%; height: 100%; cursor: pointer; left: 0; top: 0; background: rgba(0,0,0,0.4); z-index: 9; opacity: 0; visibility: hidden; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-preview-ctn .sbi-post-item-media-wrap:hover .sbi-post-overlay, .sbi-preview-ctn .sbi-post-item-iframe-ctn:hover .sbi-post-overlay, .sbi-preview-ctn .sbi-post-item-video-ctn:hover .sbi-post-overlay, .sbi-preview-ctn .sbi-post-overlay-parent:hover .sbi-post-overlay, .sbi-preview-ctn .sbi-videos-item-source:hover .sbi-post-overlay{ opacity: 1; visibility: visible; } /*Lightbox */ .sbi-lightbox-ctn{ width: 100%; height: 100%; position: absolute; left: 0; top: 2px; background: rgba(0,0,0,0.9); z-index: 9; display: none; justify-content: center; align-items: flex-start; padding-top: 100px; } .sbi-lightbox-ctn[data-visibility="shown"]{ display: flex; } .sbi-lightbox-closer{ position: absolute; left: 0; top: 0; z-index: 1; height: 100%; width: 100%; } .sbi-lightbox-image img{ float: left; max-width:780px; } .sbi-lightbox-content{ max-width: 100%; position: relative; z-index: 2; } .sbi-lightbox-content-insider{ position: relative; padding-right: 300px; display: flex; } [data-comments="false"] .sbi-lightbox-content-insider{ padding-right: 0px; } [data-comments="false"] .sbi-lightbox-content{ max-width: 100%; position: relative; z-index: 2; } .sbi-lightbox-sidebar{ width: 300px; box-sizing: border-box; position: absolute; right: 0px; top: 0px; background: #fff; height: 100%; padding: 15px; overflow: auto; } .sbi-lightbox-caption{ float: left; box-sizing: border-box; padding: 10px; background: #fff; position: relative; position: absolute; } .sbi-lightbox-caption .sbi-lightbox-cls{ top:3px; } .sbi-lightbox-sidebar .sbi-post-item-meta-top{ display: none!important; } .sbi-lightbox-sidebar .sbi-post-item-meta-comments{ display: block!important; } .sbi-lightbox-sidebar .sbi-post-item-meta-wrap{ margin-top: 12px; } .sbi-lightbox-cls{ position: absolute; width: 15px; height: 15px; top: 8px; right: 6px; cursor: pointer; z-index: 8; } .sbi-lightbox-cls:before, .sbi-lightbox-cls:after{ content: ''; position: absolute; height: 3px; width: 13px; left: 1px; top: 6px; background: currentColor; -webkit-transform: rotate(45deg); transform: rotate(45deg); } .sbi-lightbox-cls:after{ -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-lightbox-nav{ position: absolute; width: 40px; height: 100%; display: flex; justify-content: center; align-items: center; left: -60px; cursor: pointer; } .sbi-lightbox-next{ left: unset; right:-60px; } .sbi-lightbox-nav-icon{ width: 24px; height: 24px; border-bottom: 4px solid #fff; border-right: 4px solid #fff; -webkit-transform: rotate(135deg); transform: rotate(135deg); opacity: .7; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-lightbox-next .sbi-lightbox-nav-icon{ -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } .sbi-lightbox-nav:hover .sbi-lightbox-nav-icon{ opacity: 1; } .sbi-lightbox-thumbs{ background: #222; } .sbi-lightbox-thumb-item{ float: left; width: 60px; height: 60px; cursor: pointer; box-sizing: border-box; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; background-size: cover; background-position: center center; margin: 4px; } .sbi-lightbox-thumb-item:hover, .sbi-lightbox-thumb-item[data-active="true"]{ box-shadow: inset 0 0 0 4px rgb(255 255 255 / 70%); border: 1px solid #bbb; } .sbi-lightbox-sidebar .sbi-post-item-text{ line-height: 1.3em } /* COLOR SCHEMES */ /*LIGHT*/ [data-preview-colorscheme="light"] .sbi-post-item-content{ color: rgba(0,0,0,.8); } [data-preview-colorscheme="light"] .sbi-singlemedia-item-info p{ color: rgba(0,0,0,.7); } [data-preview-colorscheme="light"] .sbi-post-item-text a{ color: #141B38; text-decoration: underline; } [data-preview-colorscheme="light"] .sbi-post-item-text-expand, [data-preview-colorscheme="light"] .sbi-post-item-action-link{ color: #141B38; } [data-preview-colorscheme="light"] .sbi-post-item-date{ color: rgba(0,0,0,0.5) } /*DARK*/ [data-preview-colorscheme="dark"] .sbi-post-item-content{ color: rgba(255,255,255,.75); background-color: rgba(0,0,0,.85) } [data-preview-colorscheme="dark"] .sbi-singlemedia-item-info p{ color: rgba(255,255,255,.75); } [data-preview-colorscheme="dark"] .sbi-post-item-text a{ color: #fff; text-decoration: underline; } [data-preview-colorscheme="dark"] .sbi-post-item-text-expand, [data-preview-colorscheme="dark"] .sbi-post-item-action-link{ color: #fff; } [data-preview-colorscheme="dark"] .sbi-post-item-date{ color: rgba(255,255,255,.5); } .sbi-videos-item-ctn,.sbi-albums-item-ctn,.sbi-photos-item-ctn{ border-bottom: 0px!important; } .sbi-preview-posts-grid .sbi-videos-item-ctn .sbi-post-item-content, .sbi-preview-posts-grid .sbi-videos-item-ctn .sbi-post-overlay-parent, .sbi-preview-posts-grid .sbi-videos-item-ctn .sbi-post-overlay-parent > .sbi-fb-fs{ position: absolute; width: 100%; height: 100%; } .sbi-preview-posts-grid .sbi-videos-item-ctn .sbi-post-overlay-parent{ background-size: cover!important; background-position: center center!important; } .sbi-preview-posts-grid .sbi-videos-item-ctn .sbi-post-overlay-parent{ height: calc(100% - 70px) } .sbi-preview-posts-grid .sbi-singlemedia-item-info{ position: absolute; bottom: 0px; } /* Carousel */ .owl-stage{ position: relative; } .owl-stage-outer{ overflow: hidden; } .owl-item{ float: left; } .owl-dots{ width: 100%; height: 35px; text-align: center; margin-top: 10px; margin-bottom: 30px; display: flex; justify-content: center; align-items: center; } .owl-dot{ display: inline-block; width: 12px; height: 12px; margin: 5px 7px; filter: Alpha(Opacity=25); opacity: 0.25; padding:0px !important; border-radius: 20px; background: #000; box-shadow: 0 0 1px 0 rgb(255 255 255 / 80%); outline: none; border: 0px; cursor: pointer; } .owl-dot.active,.owl-dot:hover{ opacity: .5; } .owl-prev, .owl-next{ width: 40px; height: 40px; border-radius: 50px; padding: 0px; outline: none; border: 0px; cursor: pointer; font-size: 22px; display: flex; justify-content: center; align-items: center; background: #000; color: #fff; } .owl-dots .owl-prev, .owl-dots .owl-next{ display: inline-block; } .owl-prev span, .owl-next span{ margin-top: -3px; } .sbi-carousel[data-navigation="none"] .owl-nav{ display: none; } .sbi-carousel[data-navigation="onhover"] .owl-prev, .sbi-carousel[data-navigation="onhover"] .owl-next{ opacity: 0; position: absolute; top: 50%; margin-top: -20px; left: 0px; transition: all .2s ease-in-out; -webkit-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .sbi-carousel[data-navigation="onhover"] .owl-next{ left: unset; right: 0px; } .sbi-carousel[data-navigation="below"] .owl-prev, .sbi-carousel[data-navigation="below"] .owl-next, .sbi-carousel:hover .owl-prev, .sbi-carousel:hover .owl-next{ opacity: .5; } .sbi-carousel .owl-prev:hover, .sbi-carousel .owl-next:hover{ opacity: 1; } .sbi-carousel .cff_carousel-more{ display: block; position: relative; clear: both; width: 100%; background: none; color: #333; text-align: center; padding: 0; height: 20px; border: none; border-radius: 0; border-top: 1px solid rgba(0,0,0,0.5); margin-top: 0; background: #000; filter: Alpha(Opacity=25); opacity: 0.25; color: #fff; padding: 0; border: none; margin-top: 0; height: auto; } .sbi-carousel .cff_carousel-more:hover, .sbi-carousel .cff_carousel-more:focus{ filter: Alpha(Opacity=50); opacity: 0.5; } .sbi-carousel .cff_carousel-more .fa-caret-down { font-size: 50px; line-height: 1; padding: 0; position: relative; top: -19px; } /*Reviews Ratings*/ .sbi-rating { float: none; display: inline-block; margin: 0 0 5px 0 !important; padding: 3px 6px; height: auto; background: #5890FF; color: #fff; white-space: nowrap; border-radius: 100px; line-height: 1em; } span.sbi-rating-num, span.sbi-star { margin: 0 2px 0 0 !important; padding: 0; height: auto; display: inline-block; vertical-align: top; line-height: 1; color: #fff; font-weight: normal; font-size: 12px!important; } span.sbi-rating-num{ margin: 0 2px 0 4px !important; }admin/builder/assets/js/add-source.js000064400000035517150515074570013610 0ustar00var sbiStorage = window.localStorage; /** * Add Source Popup * * @since 4.0 */ Vue.component('sb-add-source-component', { name: 'sb-add-source-component', template: '#sb-add-source-component', props: [ 'genericText', 'links', 'svgIcons', 'viewsActive', 'selectSourceScreen', 'selectedFeed', 'parent' ], data: function() { return{ sourcesList : sbi_source.sources, nonce : sbi_source.nonce, //Add New Source newSourceData : sbi_source.newSourceData ? sbi_source.newSourceData : null, sourceConnectionURLs : sbi_source.sourceConnectionURLs, manualSourcePopupInit : sbi_source.manualSourcePopupInit, returnedApiSourcesList : [], addNewSource : { typeSelected : 'personal', manualSourceID : null, manualSourceToken : null }, selectedSourcesToConnect : [], loadingAjax : false } }, computed : { }, mounted : function(){ var self = this; if(self.newSourceData != null){ self.initAddSourceData(); } if( self.manualSourcePopupInit != undefined && self.manualSourcePopupInit == true){ self.viewsActive.sourcePopupScreen = 'step_3'; self.viewsActive.sourcePopup = true; } self.processIFConnectSuccess(); }, methods : { /** * Return Page/Group Avatar * * @since 4.0 * * @return string */ returnAccountAvatar : function(source){ if (typeof source.avatar !== "undefined" && source.avatar !== '') { return source.avatar; } else if (typeof this.newSourceData !== 'undefined' && typeof this.newSourceData.matchingExistingAccounts !== 'undefined' && typeof this.newSourceData.matchingExistingAccounts.avatar !== 'undefined') { return this.newSourceData.matchingExistingAccounts.avatar; } return false; }, /** * Add Feed Source Manually * * @since 4.0 */ addSourceManually: function(isEventSource = false){ var self = this, manualSourceData = { 'action' : 'sbi_source_builder_update', 'type' : self.addNewSource.typeSelected, 'id' : self.addNewSource.manualSourceID, 'access_token' : self.addNewSource.manualSourceToken, 'nonce' : self.nonce }; if(isEventSource){ manualSourceData.privilege = 'events'; } var alerts = document.querySelectorAll(".sb-alerts-wrap"); if (alerts.length) { alerts[0].parentNode.removeChild(alerts[0]); } if(self.$parent.checkNotEmpty(self.addNewSource.manualSourceID) && self.$parent.checkNotEmpty(self.addNewSource.manualSourceToken) ){ self.loadingAjax = true; self.$parent.ajaxPost(manualSourceData, function(_ref){ var data = _ref.data; if (typeof data.success !== 'undefined' && data.success === false) { //sbi-if-source-inputs sbi-if-fs var inputs = document.querySelectorAll(".sbi-fb-source-inputs")[0]; var div = document.createElement('div'); div.innerHTML = data.data.message; while (div.children.length > 0) { inputs.appendChild(div.children[0]); } } else { self.addNewSource = {typeSelected : 'personal', manualSourceID : null,manualSourceToken : null}; self.sourcesList = data.data; self.$parent.sourcesList = data.data; self.$parent.viewsActive.sourcePopup = false; if(self.$parent.customizerFeedData){ self.$parent.activateView('sourcePopup', 'customizer'); } } self.loadingAjax = false; }); }else{ alert("Token or ID Empty") } }, //Check if source are Array createSourcesArray : function( element ){ var self = this; if(Array.isArray(element) && element.length == 1 && !self.$parent.checkNotEmpty(element[0]) ){ return []; } var arrayResult = Array.isArray(element) ? Array.from(element) : Array.from( element.split(',') ); return arrayResult.filter(function (el) { return el != null && self.$parent.checkNotEmpty(el); }); }, /** * Make sure something entered for manual connections * * @since 4.0 */ checkManualEmpty : function() { var self = this; return self.$parent.checkNotEmpty(self.addNewSource.manualSourceID) && self.$parent.checkNotEmpty(self.addNewSource.manualSourceToken); }, /** * Init Add Source Action * Triggered when the connect button is returned * * @since 4.0 */ initAddSourceData : function(){ var self = this; // If a quick update or insert was done, skip step 2 if ( self.newSourceData.didQuickUpdate) { if(self.newSourceData.type !== 'business'){ if(self.$parent.customizerFeedData){ if(sbiStorage.feedTypeOnSourcePopup != undefined){ self.$parent.feedTypeOnSourcePopup = sbiStorage.feedTypeOnSourcePopup; if( self.$parent.feedTypeOnSourcePopup == 'tagged' ){ self.$parent.selectedSourcesPopup = self.createSourcesArray(self.$parent.selectedSourcesTagged); self.$parent.selectedSourcesTaggedPopup = self.createSourcesArray(self.$parent.selectedSourcesTagged); }else if( self.$parent.feedTypeOnSourcePopup == 'user' ){ self.$parent.selectedSourcesPopup = self.createSourcesArray(self.$parent.selectedSourcesUser); self.$parent.selectedSourcesUserPopup = self.createSourcesArray(self.$parent.selectedSourcesUser); } self.$parent.viewsActive.sourcesListPopup = true; } } } return; } self.$parent.viewsActive.sourcePopup = true; self.$parent.viewsActive.sourcePopupScreen = 'step_2'; if(self.newSourceData && !self.newSourceData.error){ if (self.newSourceData.type === 'business') { self.newSourceData.unconnectedAccounts.forEach(function(singleSource){ self.returnedApiSourcesList.push(self.createSourceObject('business',singleSource)); }); } else { self.newSourceData.unconnectedAccounts.forEach(function(singleSource){ self.returnedApiSourcesList.push(self.createSourceObject('personal',singleSource)); }); self.$parent.viewsActive.sourcePopupScreen = 'step_4'; } } }, /** * Create Single Source Object * * @since 4.0 * * @return Object */ createSourceObject : function(type,object){ return { id : object.id, account_id : object.id, access_token : object.access_token, account_type : type, type : type, avatar : object.avatar, info : JSON.stringify(object), username : object.username } }, /** * Select Page/Group to Connect * * @since 4.0 */ selectSourcesToConnect : function(source){ var self = this; if (typeof window.sbiSelected === 'undefined') { window.sbiSelected = []; } if(self.selectedSourcesToConnect.includes(source.account_id)){ self.selectedSourcesToConnect.splice(self.selectedSourcesToConnect.indexOf(source.account_id), 1); window.sbiSelected.splice(self.selectedSourcesToConnect.indexOf(source.admin), 1); }else{ self.selectedSourcesToConnect.push(source.account_id); window.sbiSelected.push(source.admin); } }, /** * Select Page/Group to Connect * * @since 4.0 */ addSourcesOnConnect : function(){ var self = this, isSingleSource = self.returnedApiSourcesList.length === 1; if(self.selectedSourcesToConnect.length > 0 || isSingleSource){ var sourcesListToAdd = []; if (self.selectedSourcesToConnect.length > 0) { self.selectedSourcesToConnect.forEach(function(accountID, index){ self.returnedApiSourcesList.forEach(function(source){ if(source.account_id === accountID) { sourcesListToAdd.push(source); } }); }); } else { self.returnedApiSourcesList.forEach(function(source){ sourcesListToAdd.push(source); }); } var connectSourceData = { 'action' : 'sbi_source_builder_update_multiple', 'type' : self.addNewSource.typeSelected, 'sourcesList' : sourcesListToAdd, 'nonce' : self.nonce }; self.$parent.ajaxPost(connectSourceData, function(_ref){ var data = _ref.data; self.sourcesList = data; self.$parent.sourcesList = data; self.$parent.viewsActive.sourcePopup = false; self.$parent.viewsActive.sourcesListPopup = false; if(self.$parent.customizerFeedData){ //self.$parent.activateView('sourcePopup', 'customizer'); self.$parent.viewsActive.sourcesListPopup = true; } }); } }, /** * Process Connect IF Button * * @since 4.0 */ processIFConnect : function(){ var self = this, ifConnectURL = self.addNewSource.typeSelected === 'personal' ? self.sourceConnectionURLs.personal : self.sourceConnectionURLs.business, screenType = (self.$parent.customizerFeedData != undefined) ? 'customizer' : 'creationProcess', appendURL = ( screenType == 'customizer' ) ? self.sourceConnectionURLs.stateURL + ',feed_id='+ self.$parent.customizerFeedData.feed_info.id : self.sourceConnectionURLs.stateURL; //if(screenType != 'customizer'){ self.createLocalStorage(screenType); //} if( self.$parent.isSetupPage === 'true'){ appendURL = appendURL+ ',is_setup_page=yes'; } var finalUrl = ifConnectURL + "{'{url=" + appendURL + "}'}"; window.location = finalUrl; }, /** * Browser Local Storage for IF Connect * * @since 4.0 */ createLocalStorage : function(screenType){ var self = this; switch (screenType) { case 'creationProcess': sbiStorage.setItem('selectedFeed', self.$parent.selectedFeed); sbiStorage.setItem('feedTypeOnSourcePopup', self.$parent.feedTypeOnSourcePopup); if( self.$parent.isSetupPage === 'true'){ sbiStorage.setItem('isSetupPage', 'true'); } break; case 'customizer': sbiStorage.setItem('selectedFeed', self.$parent.selectedFeedPopup); sbiStorage.setItem('feedTypeOnSourcePopup', self.$parent.feedTypeOnSourcePopup); sbiStorage.setItem( 'feed_id', self.$parent.customizerFeedData.feed_info.id ); break; } sbiStorage.setItem( 'IFConnect', 'true' ); sbiStorage.setItem( 'screenType', screenType ); }, /** * Process IF Connect Success * * @since 4.0 */ processIFConnectSuccess : function(){ var self = this; if( sbiStorage.IFConnect === 'true' && sbiStorage.screenType ){ if( sbiStorage?.isSetupPage === 'true' && sbiStorage?.isSetupPage ){ sbiStorage.removeItem("isSetupPage"); sbiStorage.setItem('setCurrentStep',1); window.location = window.location.href.replace('sbi-feed-builder', 'sbi-setup') ; } if( sbiStorage.screenType == 'creationProcess' && sbiStorage.selectedFeed ){ self.$parent.selectedFeed = self.createSourcesArray(sbiStorage.selectedFeed); self.$parent.feedTypeOnSourcePopup = sbiStorage.feedTypeOnSourcePopup; self.$parent.viewsActive.pageScreen = 'selectFeed'; self.$parent.viewsActive.selectedFeedSection = 'selectSource'; self.$parent.viewsActive.sourcesListPopup = true; } if( sbiStorage.screenType == 'customizer' && sbiStorage.feed_id){ var urlParams = new URLSearchParams(window.location.search); urlParams.set('feed_id', sbiStorage.feed_id); window.location.search = urlParams; } } sbiStorage.removeItem("IFConnect"); sbiStorage.removeItem("screenType"); sbiStorage.removeItem("selectedFeed"); sbiStorage.removeItem("feedTypeOnSourcePopup"); sbiStorage.removeItem("feed_id"); }, groupNext : function() { }, checkDisclaimer : function(){ return typeof window.sbiSelectedFeed !== 'undefined' && window.sbiSelectedFeed.length === 1 && window.sbiSelectedFeed[0] !== 'user'; }, printDisclaimer : function(){ return (typeof window.sbiSelectedFeed !== 'undefined' && window.sbiSelectedFeed.length === 1 && window.sbiSelectedFeed[0] === 'tagged') ? this.selectSourceScreen.modal.disclaimerMentions : this.selectSourceScreen.modal.disclaimerHashtag; }, } }); admin/builder/assets/js/date_i18n.js000064400000004470150515074570013330 0ustar00function date_i18n(n,t){function e(n,t){return i[n]?i[n]():t}function r(n,t){for(n=String(n);n.length response.json()) .then(data => { if( data.success ) { self.$parent.sourcesList = data.sourcesList; self.personalAccountPopup = false; self.$parent.successPersonalAccountUpdate(); } self.loading = false; }); }, } });admin/builder/assets/js/install-plugin-popup.js000064400000002205150515074570015651 0ustar00/** * Install Plugin Popup Popup * * @since 4.0 */ Vue.component('install-plugin-popup', { name: 'install-plugin-popup', template: '#install-plugin-popup', props: [ 'genericText', 'svgIcons', 'viewsActive', 'plugins' ], data: function() { return{ installerStatus: null } }, methods : { /** * Install or Activate Plugin * * @since 4.0 * * @return void */ installOrActivatePlugin : function( plugin, pluginPath, action ){ this.installerStatus = 'loading'; let data = new FormData(); data.append( 'action', action ); data.append( 'nonce', sbi_builder.nonce ); data.append( 'plugin', pluginPath ); data.append( 'type', 'plugin' ); fetch(sbi_builder.ajax_handler, { method: "POST", credentials: 'same-origin', body: data }) .then(response => response.json()) .then(data => { if( data.success == true ) { this.installerStatus = null; plugin.installed = true; plugin.activated = true; } return; }); }, }, }); admin/builder/assets/js/vue-color.min.js000064400000307115150515074570014253 0ustar00!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VueColor=t():e.VueColor=t()}("undefined"!=typeof self?self:this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=60)}([function(e,t){function n(e,t){var n=e[1]||"",i=e[3];if(!i)return n;if(t&&"function"==typeof btoa){var o=r(i);return[n].concat(i.sources.map(function(e){return"/*# sourceURL="+i.sourceRoot+e+" */"})).concat([o]).join("\n")}return[n].join("\n")}function r(e){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(e))))+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var r=n(t,e);return t[2]?"@media "+t[2]+"{"+r+"}":r}).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},i=0;in.parts.length&&(r.parts.length=n.parts.length)}else{for(var a=[],i=0;i0?(0,o.default)(e.hex):e&&e.hsv?(0,o.default)(e.hsv):e&&e.rgba?(0,o.default)(e.rgba):e&&e.rgb?(0,o.default)(e.rgb):(0,o.default)(e))||void 0!==n._a&&null!==n._a||n.setAlpha(r||1);var i=n.toHsl(),a=n.toHsv();return 0===i.s&&(a.h=i.h=e.h||e.hsl&&e.hsl.h||t||0),{hsl:i,hex:n.toHexString().toUpperCase(),hex8:n.toHex8String().toUpperCase(),rgba:n.toRgb(),hsv:a,oldHue:e.h||t||i.h,source:e.source,a:e.a||n.getAlpha()}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(65),o=function(e){return e&&e.__esModule?e:{default:e}}(i);t.default={props:["value"],data:function(){return{val:r(this.value)}},computed:{colors:{get:function(){return this.val},set:function(e){this.val=e,this.$emit("input",e)}}},watch:{value:function(e){this.val=r(e)}},methods:{colorChange:function(e,t){this.oldHue=this.colors.hsl.h,this.colors=r(e,t||this.oldHue)},isValidHex:function(e){return(0,o.default)(e).isValid()},simpleCheckForValidColor:function(e){for(var t=["r","g","b","a","h","s","l","v"],n=0,r=0,i=0;i0?r:n)(e)}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(12);e.exports=function(e,t){if(!r(e))return e;var n,i;if(t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;if("function"==typeof(n=e.valueOf)&&!r(i=n.call(e)))return i;if(!t&&"function"==typeof(n=e.toString)&&!r(i=n.call(e)))return i;throw TypeError("Can't convert object to primitive value")}},function(e,t){e.exports={}},function(e,t,n){var r=n(46),i=n(30);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t,n){var r=n(29)("keys"),i=n(19);e.exports=function(e){return r[e]||(r[e]=i(e))}},function(e,t,n){var r=n(15),i=n(4),o=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(e.exports=function(e,t){return o[e]||(o[e]=void 0!==t?t:{})})("versions",[]).push({version:r.version,mode:n(14)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t,n){var r=n(8).f,i=n(6),o=n(11)("toStringTag");e.exports=function(e,t,n){e&&!i(e=n?e:e.prototype,o)&&r(e,o,{configurable:!0,value:t})}},function(e,t,n){t.f=n(11)},function(e,t,n){var r=n(4),i=n(15),o=n(14),a=n(32),s=n(8).f;e.exports=function(e){var t=i.Symbol||(i.Symbol=o?{}:r.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:a.f(e)})}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(3),o=r(i),a=n(5),s=r(a),c=["#4D4D4D","#999999","#FFFFFF","#F44E3B","#FE9200","#FCDC00","#DBDF00","#A4DD00","#68CCCA","#73D8FF","#AEA1FF","#FDA1FF","#333333","#808080","#CCCCCC","#D33115","#E27300","#FCC400","#B0BC00","#68BC00","#16A5A5","#009CE0","#7B64FF","#FA28FF","#000000","#666666","#B3B3B3","#9F0500","#C45100","#FB9E00","#808900","#194D33","#0C797D","#0062B1","#653294","#AB149E"];t.default={name:"Compact",mixins:[o.default],props:{palette:{type:Array,default:function(){return c}}},components:{"ed-in":s.default},computed:{pick:function(){return this.colors.hex.toUpperCase()}},methods:{handlerClick:function(e){this.colorChange({hex:e,source:"hex"})}}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={name:"editableInput",props:{label:String,labelText:String,desc:String,value:[String,Number],max:Number,min:Number,arrowOffset:{type:Number,default:1}},computed:{val:{get:function(){return this.value},set:function(e){if(!(void 0!==this.max&&+e>this.max))return e;this.$refs.input.value=this.max}},labelId:function(){return"input__label__"+this.label+"__"+Math.random().toString().slice(2,5)},labelSpanText:function(){return this.labelText||this.label}},methods:{update:function(e){this.handleChange(e.target.value)},handleChange:function(e){var t={};t[this.label]=e,void 0===t.hex&&void 0===t["#"]?this.$emit("change",t):e.length>5&&this.$emit("change",t)},handleKeyDown:function(e){var t=this.val,n=Number(t);if(n){var r=this.arrowOffset||1;38===e.keyCode&&(t=n+r,this.handleChange(t),e.preventDefault()),40===e.keyCode&&(t=n-r,this.handleChange(t),e.preventDefault())}}}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(3),i=function(e){return e&&e.__esModule?e:{default:e}}(r),o=["#FFFFFF","#F2F2F2","#E6E6E6","#D9D9D9","#CCCCCC","#BFBFBF","#B3B3B3","#A6A6A6","#999999","#8C8C8C","#808080","#737373","#666666","#595959","#4D4D4D","#404040","#333333","#262626","#0D0D0D","#000000"];t.default={name:"Grayscale",mixins:[i.default],props:{palette:{type:Array,default:function(){return o}}},components:{},computed:{pick:function(){return this.colors.hex.toUpperCase()}},methods:{handlerClick:function(e){this.colorChange({hex:e,source:"hex"})}}}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(5),o=r(i),a=n(3),s=r(a);t.default={name:"Material",mixins:[s.default],components:{"ed-in":o.default},methods:{onChange:function(e){e&&(e.hex?this.isValidHex(e.hex)&&this.colorChange({hex:e.hex,source:"hex"}):(e.r||e.g||e.b)&&this.colorChange({r:e.r||this.colors.rgba.r,g:e.g||this.colors.rgba.g,b:e.b||this.colors.rgba.b,a:e.a||this.colors.rgba.a,source:"rgba"}))}}}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(81),o=r(i),a=n(3),s=r(a),c=n(13),l=r(c);t.default={name:"Slider",mixins:[s.default],props:{swatches:{type:Array,default:function(){return[{s:.5,l:.8},{s:.5,l:.65},{s:.5,l:.5},{s:.5,l:.35},{s:.5,l:.2}]}}},components:{hue:l.default},computed:{normalizedSwatches:function(){return this.swatches.map(function(e){return"object"!==(void 0===e?"undefined":(0,o.default)(e))?{s:.5,l:e}:e})}},methods:{isActive:function(e,t){var n=this.colors.hsl;return 1===n.l&&1===e.l||(0===n.l&&0===e.l||Math.abs(n.l-e.l)<.01&&Math.abs(n.s-e.s)<.01)},hueChange:function(e){this.colorChange(e)},handleSwClick:function(e,t){this.colorChange({h:this.colors.hsl.h,s:t.s,l:t.l,source:"hsl"})}}}},function(e,t,n){"use strict";var r=n(14),i=n(41),o=n(44),a=n(7),s=n(26),c=n(88),l=n(31),u=n(95),f=n(11)("iterator"),d=!([].keys&&"next"in[].keys()),h=function(){return this};e.exports=function(e,t,n,p,v,g,b){c(n,t,p);var x,m,_,w=function(e){if(!d&&e in F)return F[e];switch(e){case"keys":case"values":return function(){return new n(this,e)}}return function(){return new n(this,e)}},y=t+" Iterator",C="values"==v,k=!1,F=e.prototype,S=F[f]||F["@@iterator"]||v&&F[v],A=S||w(v),O=v?C?w("entries"):A:void 0,E="Array"==t?F.entries||S:S;if(E&&(_=u(E.call(new e)))!==Object.prototype&&_.next&&(l(_,y,!0),r||"function"==typeof _[f]||a(_,f,h)),C&&S&&"values"!==S.name&&(k=!0,A=function(){return S.call(this)}),r&&!b||!d&&!k&&F[f]||a(F,f,A),s[t]=A,s[y]=h,v)if(x={values:C?A:w("values"),keys:g?A:w("keys"),entries:O},b)for(m in x)m in F||o(F,m,x[m]);else i(i.P+i.F*(d||k),t,x);return x}},function(e,t,n){var r=n(4),i=n(15),o=n(86),a=n(7),s=n(6),c=function(e,t,n){var l,u,f,d=e&c.F,h=e&c.G,p=e&c.S,v=e&c.P,g=e&c.B,b=e&c.W,x=h?i:i[t]||(i[t]={}),m=x.prototype,_=h?r:p?r[t]:(r[t]||{}).prototype;h&&(n=t);for(l in n)(u=!d&&_&&void 0!==_[l])&&s(x,l)||(f=u?_[l]:n[l],x[l]=h&&"function"!=typeof _[l]?n[l]:g&&u?o(f,r):b&&_[l]==f?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(f):v&&"function"==typeof f?o(Function.call,f):f,v&&((x.virtual||(x.virtual={}))[l]=f,e&c.R&&m&&!m[l]&&a(m,l,f)))};c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){e.exports=!n(9)&&!n(17)(function(){return 7!=Object.defineProperty(n(43)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var r=n(12),i=n(4).document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},function(e,t,n){e.exports=n(7)},function(e,t,n){var r=n(16),i=n(89),o=n(30),a=n(28)("IE_PROTO"),s=function(){},c=function(){var e,t=n(43)("iframe"),r=o.length;for(t.style.display="none",n(94).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write("