Changeset 3732789
- Timestamp:
- 10/07/2026 02:24:16 PM (3 weeks ago)
- Location:
- plugupp-link-image-health-audit/trunk
- Files:
-
- 9 edited
-
assets/shared/admin-controls.css (modified) (2 diffs)
-
includes/class-admin-controls.php (modified) (1 diff)
-
plugupp-link-image-health-audit.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
-
vendor/freemius/includes/class-freemius.php (modified) (18 diffs)
-
vendor/freemius/includes/managers/class-fs-clone-manager.php (modified) (5 diffs)
-
vendor/freemius/start.php (modified) (1 diff)
-
vendor/freemius/templates/add-ons.php (modified) (4 diffs)
-
vendor/freemius/templates/pricing.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
plugupp-link-image-health-audit/trunk/assets/shared/admin-controls.css
r3715587 r3732789 32 32 * slot (`plugupp-field-slot-stack`): two companions shown one under the 33 33 * other when their deciding control shows both. 34 * - 0.2.4 caps a field's text input at its field at every width (core's 35 * fixed widths become maxima), so a core `regular-text` in a narrow slot 36 * never runs past it. 34 37 * 35 38 * CANONICAL SOURCE - edit in _shared/shared-admin-controls/src/, re-run sync.sh. … … 130 133 flex-wrap: nowrap; 131 134 } 135 /* A field's text input is never wider than its field (0.2.4, 2026-09-27). 136 * Core gives inputs fixed widths (`.regular-text` 25em, 350px; `.large-text` 137 * 99%) and caps `.regular-text` at 100% only below its 782px breakpoint, so 138 * above it a 350px input in a narrower field or slot ran past it: Folder 139 * Flow's First breadcrumb text, 350px in a 232px slot beside its row of 140 * buttons in a tab panel, ran 119px past the slot and 99px past the card, and 141 * scrolled the page 79px sideways, at 783 (measured on both FFG staging 142 * sites; tests/layout reproduces it). Core's width is now a maximum, never a 143 * reason to run past the box, at every width. `calc( 100% - 2px )` leaves 144 * room for core's `input { margin: 0 1px }`, so the input's margin box fills 145 * the field exactly; a textarea has no margin. 146 * 147 * ZERO SPECIFICITY (`:where()`) IS LOAD-BEARING: the cap is only a default. 148 * Any maximum already set wins over it, so nothing that had one changes: a 149 * consumer's own cap on a field's textarea (FFG's 420px folder lists), core's 150 * phone-band caps (`.small-text` 4.375em, `.regular-text` 100% where 0.2.2 151 * removes the margins, `.form-table td` inputs none). A first cut at (0,2,1) 152 * overrode them all (FFG's diff, 2026-09-27). A select keeps its own rule. */ 153 :where(.plugupp-field) :where(input[type="text"], input[type="password"], input[type="email"], input[type="url"], input[type="number"], input[type="search"], input[type="tel"], input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"], input[type="week"], input:not([type])) { 154 max-width: calc( 100% - 2px ); 155 } 156 :where(.plugupp-field) :where(textarea) { 157 max-width: 100%; 158 } 132 159 /* Below core's 782px admin breakpoint the pair wraps (0.2.2, ruled 133 160 * 2026-09-27): a pair that never wraps ran 166px past the card, and scrolled -
plugupp-link-image-health-audit/trunk/includes/class-admin-controls.php
r3715587 r3732789 47 47 48 48 /** Component version (the VERSION file; sync.sh prints it). */ 49 const VERSION = '0.2. 3';49 const VERSION = '0.2.4'; 50 50 51 51 /** -
plugupp-link-image-health-audit/trunk/plugupp-link-image-health-audit.php
r3715587 r3732789 5 5 * Plugin URI: https://plugupp.com/plugupp-link-image-health-audit/ 6 6 * Description: Finds broken links, broken images and SSL problems by auditing the final rendered output of every page - locally, with no external service and no link quotas. 7 * Version: 1.5. 07 * Version: 1.5.1 8 8 * Author: PlugUpp 9 9 * Author URI: https://plugupp.com/ … … 70 70 // Constants 71 71 // --------------------------------------------------------------------- 72 define( 'LIHA_VERSION', '1.5. 0' );72 define( 'LIHA_VERSION', '1.5.1' ); 73 73 define( 'LIHA_ENGINE_VERSION', '0.7.1' ); 74 74 // Bundled render-engine source version. 75 define( 'LIHA_ADMIN_CONTROLS_VERSION', '0.2. 3' );75 define( 'LIHA_ADMIN_CONTROLS_VERSION', '0.2.4' ); 76 76 // Bundled shared-admin-controls version (its sync.sh prints it). 77 77 define( 'LIHA_PLUGIN_FILE', __FILE__ ); -
plugupp-link-image-health-audit/trunk/readme.txt
r3715587 r3732789 5 5 Tested up to: 7.1 6 6 Requires PHP: 7.4 7 Stable tag: 1.5. 07 Stable tag: 1.5.1 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 132 132 == Changelog == 133 133 134 = 1.5.1 = 135 * Security: updated the bundled Freemius library to version 2.13.5. It fixes how some account and licence messages are shown in your admin. 136 * Fixed: minor bug fixes. 137 134 138 = 1.5.0 = 135 139 * Improved: a clearer Settings screen. Your settings sit on one card, grouped in the order you set them up: what to scan, how links are checked, and scan speed. Settings that are on or off are now switches. … … 180 184 = 1.0.4 = 181 185 * Initial public release. 186 187 == Upgrade Notice == 188 189 = 1.5.1 = 190 Security update to the bundled Freemius library. Please update. -
plugupp-link-image-health-audit/trunk/vendor/freemius/includes/class-freemius.php
r3602681 r3732789 4541 4541 4542 4542 if ( $this->is_user_in_admin() ) { 4543 if ( $this->is_registered() && fs_request_has( 'purchase_completed' ) ) {4544 $this->_admin_notices->add_sticky(4545 sprintf(4546 /* translators: %s: License type (e.g. you have a professional license) */4547 $this->get_text_inline( 'You have purchased a %s license.', 'you-have-x-license' ),4548 fs_request_get( 'purchased_plan' )4549 ) .4550 sprintf(4551 $this->get_text_inline(" The %s's %sdownload link%s, license key, and installation instructions have been sent to %s. If you can't find the email after 5 min, please check your spam box.", 'post-purchase-email-sent-message' ),4552 $this->get_module_label( true ),4553 ( FS_Plugin::is_valid_id( $this->get_bundle_id() ) ? "products' " : '' ),4554 ( FS_Plugin::is_valid_id( $this->get_bundle_id() ) ? 's' : '' ),4555 sprintf(4556 '<strong>%s</strong>',4557 fs_request_get( 'purchase_email' )4558 )4559 ),4560 'plan_purchased',4561 $this->get_text_x_inline( 'Yee-haw', 'interjection expressing joy or exuberance', 'yee-haw' ) . '!'4562 );4563 }4564 4565 4543 if ( $this->is_addon() ) { 4566 4544 if ( ! $this->is_parent_plugin_installed() ) { … … 4864 4842 $code = empty( $result->error->code ) ? '' : " Code: {$result->error->code}"; 4865 4843 4866 $error_message .= "<b>{$result->error->message}{$code}</b>"; 4844 // We do not send HTML from exceptions from Freemius servers, but we escape it nonetheless. 4845 $error_message .= "<b>" . esc_html( $result->error->message . $code ) . "</b>"; 4867 4846 } else { 4868 $error_message .= var_export( $result, true);4847 $error_message .= esc_html( var_export( $result, true ) ); 4869 4848 } 4870 4849 … … 6798 6777 } 6799 6778 6779 $escaped_email_address = esc_html( $email_address ); 6780 6800 6781 $formatted_message_args = array( 6801 6782 "<b>{$this->get_plugin_name()}</b>", 6802 "<b>{$e mail_address}</b>",6783 "<b>{$escaped_email_address}</b>", 6803 6784 ); 6804 6785 … … 6845 6826 6846 6827 $formatted_message_args[] = ( ! empty( $support_email_address ) ) ? 6847 ( "<b> {$support_email_address}</b>" ) :6828 ( "<b>" . esc_html( $support_email_address ) . "</b>" ) : 6848 6829 $this->get_text_x_inline( 6849 6830 "the product's support email address", … … 17565 17546 } 17566 17547 17548 // Only site administrators who can activate plugins may opt-in. 17549 if ( ! $this->is_user_admin() ) { 17550 return; 17551 } 17552 17567 17553 $has_pending_activation_confirmation_param = fs_request_has( 'pending_activation' ); 17568 17554 … … 18144 18130 $this->_admin_notices->add( 18145 18131 sprintf( $this->get_text_inline( 'Couldn\'t activate %s.', 'could-not-activate-x' ), $this->get_plugin_name() ) . ' ' . 18146 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . $result->error->message. '</b>',18132 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . esc_html( $result->error->message ) . '</b>', 18147 18133 $this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...', 18148 18134 'error' … … 18264 18250 $this->_admin_notices->add( 18265 18251 sprintf( $this->get_text_inline( 'Couldn\'t activate %s.', 'could-not-activate-x' ), $this->get_plugin_name() ) . ' ' . 18266 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . $error_message. '</b>',18252 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . esc_html( $error_message ) . '</b>', 18267 18253 $this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...', 18268 18254 'error' … … 18441 18427 $this->_admin_notices->add( 18442 18428 sprintf( $this->get_text_inline( 'Couldn\'t activate %s.', 'could-not-activate-x' ), $this->get_plugin_name() ) . ' ' . 18443 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . $parent_install->error->message. '</b>',18429 $this->get_text_inline( 'Please contact us with the following message:', 'contact-us-with-error-message' ) . ' ' . '<b>' . esc_html( $parent_install->error->message ) . '</b>', 18444 18430 $this->get_text_x_inline( 'Oops', 'exclamation', 'oops' ) . '...', 18445 18431 'error' … … 21159 21145 // Authentication params are broken. 21160 21146 $this->_admin_notices->add( 21161 $this->get_text_inline( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'wrong-authentication-param-message' ) . '<br> ' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . var_export( $result->error, true),21147 $this->get_text_inline( 'It seems like one of the authentication parameters is wrong. Update your Public Key, Secret Key & User ID, and try again.', 'wrong-authentication-param-message' ) . '<br> ' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . esc_html( var_export( $result->error, true ) ), 21162 21148 '', 21163 21149 'error' … … 21480 21466 sprintf( 21481 21467 '<a href="%s">%s</a>', 21482 $this->contact_url( 'bug'),21468 esc_url( $this->contact_url( 'bug' ) ), 21483 21469 $this->get_text_inline( 'Please contact us here', 'contact-us-here' ) 21484 21470 ), … … 21573 21559 '<div class="fs-api-request-error-details" style="display: none">' . 21574 21560 '<strong>' . $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . '</strong><br>' . 21575 $result->error->message.21561 esc_html( $result->error->message ) . 21576 21562 '</div>'; 21577 21563 … … 21678 21664 $this->get_text_inline( 'It looks like the license could not be activated.', 'license-activation-failed-message' ), 21679 21665 ( is_object( $license ) && isset( $license->error ) ? 21680 $license->error->message:21666 esc_html( $license->error->message ) : 21681 21667 sprintf( '%s<br><code>%s</code>', 21682 21668 $this->get_text_inline( 'Error received from the server:', 'server-error-message' ), 21683 var_export( $license, true)21669 esc_html( var_export( $license, true ) ) 21684 21670 ) 21685 21671 ) … … 21769 21755 $this->_admin_notices->add( 21770 21756 $this->get_text_inline( 'It looks like the license deactivation failed.', 'license-deactivation-failed-message' ) . '<br> ' . 21771 $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . ' ' . var_export( $license->error, true),21757 $this->get_text_inline( 'Error received from the server:', 'server-error-message' ) . ' ' . esc_html( var_export( $license->error, true ) ), 21772 21758 $hmm_text, 21773 21759 'error' … … 22418 22404 sprintf( 22419 22405 '<a href="%s" target="_blank" rel="noopener">%s</a>', 22420 $this->get_account_url( 'download_latest'),22406 esc_url( $this->get_account_url( 'download_latest' ) ), 22421 22407 sprintf( 22422 22408 /* translators: %s: plan name (e.g. latest "Professional" version) */ … … 22836 22822 $this->_admin_notices->add( sprintf( 22837 22823 $this->get_text_inline( 'Verification mail was just sent to %s. If you can\'t find it after 5 min, please check your spam box.', 'verification-email-sent-message' ), 22838 sprintf( '<a href="mailto:%1$s">%2$s</a>', esc_url( $this->_user->email ), $this->_user->email)22824 sprintf( '<a href="mailto:%1$s">%2$s</a>', esc_url( $this->_user->email ), esc_html( $this->_user->email ) ) 22839 22825 ) ); 22840 22826 } else { … … 23160 23146 if ( $this->init_change_owner( $candidate_email, $transfer_type ) ) { 23161 23147 if ( 'transfer' === $transfer_type ) { 23162 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. The email owner must confirm the update within the next 4 hours.', 'change-owner-request-sent-x-transfer' ), '<b>' . $this->_user->email. '</b>' ) );23148 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. The email owner must confirm the update within the next 4 hours.', 'change-owner-request-sent-x-transfer' ), '<b>' . esc_html( $this->_user->email ) . '</b>' ) ); 23163 23149 } else { 23164 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder.', 'change-owner-request-sent-x' ), '<b>' . $this->_user->email. '</b>' ) );23150 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'A confirmation email was just sent to %s. You must confirm the update within the next 4 hours. If you cannot find the email, please check your spam folder.', 'change-owner-request-sent-x' ), '<b>' . esc_html( $this->_user->email ) . '</b>' ) ); 23165 23151 } 23166 23152 } … … 23174 23160 } 23175 23161 23176 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'Thanks for confirming the ownership change. An email was just sent to %s for final approval.', 'change-owner-request_owner-confirmed' ), '<b>' . $candidate_email. '</b>' ) );23162 $this->_admin_notices->add( sprintf( $this->get_text_inline( 'Thanks for confirming the ownership change. An email was just sent to %s for final approval.', 'change-owner-request_owner-confirmed' ), '<b>' . esc_html( $candidate_email ) . '</b>' ) ); 23177 23163 break; 23178 23164 case 'candidate_confirmed': … … 23180 23166 if ( $this->complete_change_owner() ) { 23181 23167 $this->_admin_notices->add_sticky( 23182 sprintf( $this->get_text_inline( '%s is the new owner of the account.', 'change-owner-request_candidate-confirmed' ), '<b>' . $this->_user->email. '</b>' ),23168 sprintf( $this->get_text_inline( '%s is the new owner of the account.', 'change-owner-request_candidate-confirmed' ), '<b>' . esc_html( $this->_user->email ) . '</b>' ), 23183 23169 'ownership_changed', 23184 23170 $this->get_text_x_inline( 'Congrats', 'as congratulations', 'congrats' ) . '!' -
plugupp-link-image-health-audit/trunk/vendor/freemius/includes/managers/class-fs-clone-manager.php
r3602681 r3732789 1224 1224 1225 1225 foreach ( $product_titles as $product_title ) { 1226 $products_list .= sprintf( '<li>%s</li>', $product_title);1226 $products_list .= sprintf( '<li>%s</li>', esc_html( $product_title ) ); 1227 1227 } 1228 1228 … … 1232 1232 $sites_list .= sprintf( 1233 1233 '<li><a href="%s" target="_blank">%s</a></li>', 1234 $site_url,1235 fs_strip_url_protocol( $site_url)1234 esc_url( $site_url ), 1235 esc_html( fs_strip_url_protocol( $site_url ) ) 1236 1236 ); 1237 1237 } … … 1243 1243 sprintf( 1244 1244 '<a href="%s" target="_blank">%s</a>', 1245 $site_urls[0],1246 fs_strip_url_protocol( $site_urls[0])1245 esc_url( $site_urls[0] ), 1246 esc_html( fs_strip_url_protocol( $site_urls[0] ) ) 1247 1247 ) : 1248 1248 fs_text_inline( 'the above-mentioned sites', 'above-mentioned-sites' )) . '</b>'; … … 1250 1250 $current_site_link = sprintf( 1251 1251 '<b><a href="%s" target="_blank">%s</a></b>', 1252 $current_url,1253 fs_strip_url_protocol( $current_url)1252 esc_url( $current_url ), 1253 esc_html( fs_strip_url_protocol( $current_url ) ) 1254 1254 ); 1255 1255 … … 1324 1324 // %1$s 1325 1325 ( 1 === $total_products ? 1326 sprintf( '<b>%s</b>', $product_titles[0]) :1326 sprintf( '<b>%s</b>', esc_html( $product_titles[0] ) ) : 1327 1327 ( 1 === $total_sites ? 1328 1328 sprintf( '<div>%s</div>', $products_list ) : -
plugupp-link-image-health-audit/trunk/vendor/freemius/start.php
r3602681 r3732789 16 16 * @var string 17 17 */ 18 $this_sdk_version = '2.13. 4';18 $this_sdk_version = '2.13.5'; 19 19 20 20 #region SDK Selection Logic -------------------------------------------------------------------- -
plugupp-link-image-health-audit/trunk/vendor/freemius/templates/add-ons.php
r3602681 r3732789 123 123 $open_addon = ( $open_addon || ( $open_addon_slug === $addon->slug ) ); 124 124 125 $price = 0; 126 $has_trial = false; 125 $price = 0; 126 $min_price = 999999; 127 $has_trial = false; 127 128 $has_free_plan = false; 128 129 $has_paid_plan = false; … … 142 143 } 143 144 144 145 145 $has_paid_plan = true; 146 146 $has_trial = $has_trial || ( is_numeric( $plan->trial_period ) && ( $plan->trial_period > 0 ) ); 147 147 148 $min_price = 999999;149 148 foreach ( $plan->pricing as $pricing ) { 150 149 $pricing = new FS_Pricing( $pricing ); … … 164 163 } else if ( $pricing->has_monthly() ) { 165 164 $min_price = min( $min_price, 12 * $pricing->monthly_price ); 166 } 165 } else if ( $pricing->has_lifetime() ) { 166 $min_price = min( $min_price, $pricing->lifetime_price ); 167 } 167 168 } 168 169 … … 170 171 $price = $min_price; 171 172 } 172 173 173 } 174 174 } -
plugupp-link-image-health-audit/trunk/vendor/freemius/templates/pricing.php
r3602681 r3732789 25 25 26 26 $context_params = array( 27 // Plugin information 27 28 'plugin_id' => $fs->get_id(), 28 29 'plugin_public_key' => $fs->get_public_key(), 29 30 'plugin_version' => $fs->get_plugin_version(), 31 32 // React pricing app context 33 'contact_url' => $fs->contact_url(), 34 'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ), 35 'menu_slug' => $fs->get_menu_slug(), 36 'mode' => 'dashboard', 37 'fs_wp_endpoint_url' => WP_FS__ADDRESS, 38 'request_handler_url' => admin_url( 39 'admin-ajax.php?' . http_build_query( array( 40 'module_id' => $fs->get_id(), 41 'action' => $fs->get_ajax_action( 'pricing_ajax_action' ), 42 'security' => $fs->get_ajax_security( 'pricing_ajax_action' ) 43 ) ) 44 ), 45 'selector' => '#fs_pricing_wrapper', 46 'unique_affix' => $fs->get_unique_affix(), 47 'show_annual_in_monthly' => $fs->apply_filters( 'pricing/show_annual_in_monthly', true ), 48 'license' => $fs->has_active_valid_license() ? $fs->_get_license() : null, 49 'plugin_icon' => $fs->get_local_icon_url(), 50 'disable_single_package' => $fs->apply_filters( 'pricing/disable_single_package', false ), 30 51 ); 31 52 … … 55 76 } 56 77 57 $query_params = array_merge( $ context_params, $_GET, array(78 $query_params = array_merge( $_GET, array( 58 79 'next' => $fs->_get_sync_license_url( false, false ), 59 'plugin_version' => $fs->get_plugin_version(),60 80 // Billing cycle. 61 81 'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ), … … 64 84 'discounts_model' => $fs->apply_filters( 'pricing/discounts_model', 'absolute' ), 65 85 ) ); 86 87 $has_tabs = $fs->_add_tabs_before_content(); 88 89 if ( $has_tabs ) { 90 $query_params['tabs'] = 'true'; 91 } 92 93 $pricing_config = array_merge( $query_params, $context_params ); 66 94 67 95 $pricing_js_url = fs_asset_url( $fs->get_pricing_js_path() ); … … 73 101 wp_enqueue_style( 'freemius-pricing', fs_asset_url( $pricing_css_path ) ); 74 102 } 75 76 $has_tabs = $fs->_add_tabs_before_content();77 78 if ( $has_tabs ) {79 $query_params['tabs'] = 'true';80 }81 103 ?> 82 104 <div id="fs_pricing" class="wrap fs-section fs-full-size-wrapper"> 83 105 <div id="fs_pricing_wrapper" data-public-url="<?php echo trailingslashit( dirname( $pricing_js_url ) ) ?>"></div> 84 <?php 85 $pricing_config = array_merge( array( 86 'contact_url' => $fs->contact_url(), 87 'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ), 88 'menu_slug' => $fs->get_menu_slug(), 89 'mode' => 'dashboard', 90 'fs_wp_endpoint_url' => WP_FS__ADDRESS, 91 'request_handler_url' => admin_url( 92 'admin-ajax.php?' . http_build_query( array( 93 'module_id' => $fs->get_id(), 94 'action' => $fs->get_ajax_action( 'pricing_ajax_action' ), 95 'security' => $fs->get_ajax_security( 'pricing_ajax_action' ) 96 ) ) 97 ), 98 'selector' => '#fs_pricing_wrapper', 99 'unique_affix' => $fs->get_unique_affix(), 100 'show_annual_in_monthly' => $fs->apply_filters( 'pricing/show_annual_in_monthly', true ), 101 'license' => $fs->has_active_valid_license() ? $fs->_get_license() : null, 102 'plugin_icon' => $fs->get_local_icon_url(), 103 'disable_single_package' => $fs->apply_filters( 'pricing/disable_single_package', false ), 104 ), $query_params ); 105 106 wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' ); 107 ?> 106 <?php wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' ); ?> 108 107 </div> 109 108 <?php
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)