diff --git a/README.md b/README.md index 8d519dc4..dc82ad68 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ **Requires at least:** 6.6 \ **Tested up to:** 6.8 \ **Requires PHP:** 7.4 \ -**Stable tag:** 3.5.0 \ +**Stable tag:** 3.6.0 \ **License:** GPLv2 or later Ally: Make your site more inclusive by scanning for accessibility violations, fixing them easily, and adding a usability widget and accessibility statement. @@ -187,6 +187,10 @@ Yes. You can rescan a URL as often as needed. Results update each time based on These are smart suggestions generated by Ally to help you resolve issues more efficiently-like automatically suggesting alternative text for images. AI fixes are available only on paid plans and use credits. +### How can I report security bugs? + +You can report security bugs through the Patchstack Vulnerability Disclosure Program. The Patchstack team help validate, triage and handle any security vulnerabilities. [Report a security vulnerability](https://patchstack.com/database/wordpress/plugin/pojo-accessibility/vdp). + ## Screenshots @@ -213,6 +217,31 @@ These are smart suggestions generated by Ally to help you resolve issues more ef ## Changelog +### 3.6.0 - 2025-08-02 + +* New: Smart color contrast remediation flow in the accessibility assistant +* Tweak: Updated scan dashboard to show open issues and issue breakdown by category +* Tweak: Tooltip on analytics tab encouraging tracking activation +* Tweak: Improve accessibility column in WP admin for better user experience +* Fix: Added WPML compatibility +* Fix: WooCommerce AJAX conflict + + +### 3.5.2 - 2025-07-28 + +* Tweak: Improved performance by enqueuing Assistant only when logged in +* Fix: Admin post columns offset warning + +### 3.5.1 - 2025-07-23 + +* Tweak: Admin panel UI updates +* Tweak: Assistant UI updates +* Tweak: Ensure case sensitive attributes in remediations +* Fix: Assistant accessibility issues +* Fix: Custom Icon issue in edge cases +* Fix: Critical Error on plugin conflict + + ### 3.5.0 - 2025-07-08 * New: Introducing URL Scanner – find 180+ issues instantly (WCAG 2.1 AA) diff --git a/assets/dev/css/ea11y-scanner-admin.scss b/assets/dev/css/ea11y-scanner-admin.scss index 80f567d2..867008e6 100644 --- a/assets/dev/css/ea11y-scanner-admin.scss +++ b/assets/dev/css/ea11y-scanner-admin.scss @@ -1,5 +1,5 @@ #accessibility_status, .accessibility_status { - width: 265px; + width: auto; } .accessibility_status.column-accessibility_status { @@ -10,7 +10,7 @@ gap: 16px; justify-content: space-between; align-items: center; - width: 265px; + width: auto; &__stats { display: flex; @@ -61,12 +61,160 @@ } &__actions { + display: flex; + justify-content: center; + align-items: center; + .button { - width: 112px; + min-width: 80px; text-align: center; } } } +} + +/* CSS tooltips */ +.ea11y-tooltip { + position: relative; + + &::after { + display: none; + position: absolute; + z-index: 9999999; + padding: 6px 8px 5px; + border-radius: 3px; + opacity: 0; + color: #fff; + background: rgba(0, 0, 0, 0.8); + text-shadow: none; + font: normal normal 11px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; + text-align: center; + white-space: nowrap; + text-decoration: none; + letter-spacing: normal; + text-transform: none; + word-wrap: break-word; + content: attr(data-label); + pointer-events: none; + -webkit-font-smoothing: subpixel-antialiased; + } + + &::before { + display: none; + position: absolute; + z-index: 9999999; + width: 0; + height: 0; + border: 5px solid transparent; + opacity: 0; + color: rgba(0, 0, 0, 0.8); + content: "\00a0"; + pointer-events: none; + } + + &:hover::before, + &:hover::after, + &:focus::before, + &:focus::after { + display: inline-block; + text-decoration: none; + animation-name: ea11y-tooltip-appear; + animation-duration: 0.1s; + animation-timing-function: ease-in; + animation-fill-mode: forwards; + } + + // North tooltip (above button) + &-n::after { + right: 50%; + bottom: 100%; + margin-bottom: 5px; + transform: translateX(50%); + } + + &-n::before { + top: -5px; + right: 50%; + bottom: auto; + margin-right: -5px; + border-top-color: rgba(0, 0, 0, 0.8); + } + + // Hide tooltips when not needed + &-hidden::before, + &-hidden::after { + display: none !important; + } +} + +@keyframes ea11y-tooltip-appear { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +/* Accessibility button enhancements */ +.ea11y-accessibility-button { + position: relative; + transition: all 0.2s ease; + overflow: visible; /* IE 11 needs this for buttons */ + min-height: 24px !important; + font-size: 11px !important; + + &:hover { + transform: translateY(-1px); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + &:focus { + outline: 2px solid #0073aa; + outline-offset: 1px; + } + + .ea11y-button-text { + white-space: nowrap; + transition: all 0.2s ease; + } +} + +/* Column title responsive behavior */ +.ea11y-column-title { + transition: opacity 0.2s ease; +} + +/* Hide column title when column is too narrow */ +@container (max-width: 80px) { + .ea11y-column-title { + display: none; + } +} + +/* Fallback for browsers without container queries */ +@media screen and (max-width: 480px) { + .ea11y-column-title { + display: none; + } +} + +/* Responsive behavior for narrow columns */ +@media screen and (max-width: 782px) { + .ea11y-accessibility-button .ea11y-button-text { + font-size: 11px; + } +} + +/* Dark mode support */ +@media (prefers-color-scheme: dark) { + .ea11y-tooltip::after { + background: #2c3338; + color: #f0f0f1; + } + + .ea11y-tooltip-n::before { + border-top-color: #2c3338; + } } diff --git a/assets/dev/css/ea11y-scanner-wizard.scss b/assets/dev/css/ea11y-scanner-wizard.scss index 3526cda7..d45d1197 100644 --- a/assets/dev/css/ea11y-scanner-wizard.scss +++ b/assets/dev/css/ea11y-scanner-wizard.scss @@ -4,7 +4,8 @@ gap: 6px; } -.ea11y-scanner-current-element { +.ea11y-scanner-current-element, .ea11y-scanner-color-element, .ea11y-scanner-background-element { + box-sizing: border-box; border: 4px solid #2563EB; border-radius: 4px; } @@ -20,4 +21,6 @@ overflow-y: scroll; overflow-x: visible; z-index: 999999; + pointer-events: none; + font-family: "Roboto", "Helvetica", "Arial", sans-serif; } diff --git a/assets/dev/js/services/mixpanel/mixpanel-events.js b/assets/dev/js/services/mixpanel/mixpanel-events.js index 1369e9f0..b3627e84 100644 --- a/assets/dev/js/services/mixpanel/mixpanel-events.js +++ b/assets/dev/js/services/mixpanel/mixpanel-events.js @@ -46,6 +46,10 @@ export const mixpanelEvents = { applyFixButtonClicked: 'apply_fix_button_clicked', copySnippetClicked: 'copy_snippet_clicked', editSnippetClicked: 'edit_snippet_clicked', + contrastColorChanged: 'contrast_color_changed', + contrastResetClicked: 'contrast_reset_clicked', + backgroundAdaptorTriggered: 'background_adaptor_triggered', + backgroundAdaptorChanged: 'background_adaptor_changed', // Accessibility assistant dashboard assistantDashboardHistoryLogsButtonClicked: 'history_logs_button_clicked', diff --git a/assets/dev/js/services/mixpanel/mixpanel-service.js b/assets/dev/js/services/mixpanel/mixpanel-service.js index 4df7fc34..880fec3b 100644 --- a/assets/dev/js/services/mixpanel/mixpanel-service.js +++ b/assets/dev/js/services/mixpanel/mixpanel-service.js @@ -17,6 +17,8 @@ const init = async () => { } const pluginEnv = ea11ySettingsData?.pluginEnv || ea11yScannerData?.pluginEnv; + const pluginVersion = + ea11ySettingsData?.pluginVersion || ea11yScannerData?.pluginVersion; await mixpanel.init(MIXPANEL_TOKEN, { debug: pluginEnv === 'dev', @@ -27,6 +29,7 @@ const init = async () => { mixpanel.register({ productName: 'app_access', appType: 'Apps', + version: pluginVersion, environment: pluginEnv, is_trial: Boolean(plan?.name?.toLowerCase().includes('free')), plan_type: plan?.name, @@ -41,6 +44,7 @@ const init = async () => { $subscription_type: plan?.name, $subscription_id: plan?.subscription_id, $subscription_status: plan?.status, + $scanned_urls: `${planData?.scannedPages?.used || 0}/${planData?.scannedPages?.allowed || 0}`, }; mixpanel.people?.set_once(userData); diff --git a/assets/images/check-icon.svg b/assets/images/check-icon.svg new file mode 100644 index 00000000..4d661195 --- /dev/null +++ b/assets/images/check-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/refresh-scan.svg b/assets/images/refresh-scan.svg index ee59a279..6d52289e 100644 --- a/assets/images/refresh-scan.svg +++ b/assets/images/refresh-scan.svg @@ -1,4 +1,4 @@ - - - + + + diff --git a/classes/utils/assets.php b/classes/utils/assets.php index 8abc9d2f..b8ac29fa 100644 --- a/classes/utils/assets.php +++ b/classes/utils/assets.php @@ -104,10 +104,9 @@ private static function get_assets_path( string $asset_name, string $asset_type, * @param string $handle * @param bool $with_css */ - public static function enqueue_app_assets( string $handle = '', bool $with_css = true ) : void { + public static function enqueue_app_assets( string $handle = '', bool $with_css = true, array $dependencies = [] ) : void { $dir = \EA11Y_ASSETS_PATH . 'build/'; $url = \EA11Y_ASSETS_URL . 'build/'; - $script_asset_path = $dir . $handle . '.asset.php'; if ( ! file_exists( $script_asset_path ) ) { throw new \Error( @@ -120,7 +119,7 @@ public static function enqueue_app_assets( string $handle = '', bool $with_css = wp_enqueue_script( $handle, $url . $handle . '.js', - array_merge( $script_asset['dependencies'], [ 'wp-util', 'wp-block-editor', 'wp-components' ] ), + array_merge( $script_asset['dependencies'], $dependencies ), $script_asset['version'], true, ); diff --git a/modules/connect/classes/utils.php b/modules/connect/classes/utils.php index 509b7f33..c2faa1e5 100644 --- a/modules/connect/classes/utils.php +++ b/modules/connect/classes/utils.php @@ -21,11 +21,11 @@ public static function get_clients_url(): string { /** * get_redirect_uri * - * @param string $domain + * @param mixed|string|null $domain * * @return string */ - public static function get_redirect_uri( string $domain = '' ) : string { + public static function get_redirect_uri( $domain = null ) : string { if ( false !== strpos( Config::ADMIN_PAGE, '?page=' ) ) { $admin_url = admin_url( Config::ADMIN_PAGE ); } else { @@ -114,12 +114,13 @@ public static function get_base_url(): string { */ public static function is_valid_home_url(): bool { static $valid = null; + $saved = Data::get_home_url(); if ( null === $valid ) { - if ( empty( Data::get_home_url() ) ) { + if ( empty( $saved ) ) { $valid = true; } else { - $valid = Data::get_home_url() === home_url(); + $valid = $saved === apply_filters( 'ally_connect_home_url', home_url() ); } } diff --git a/modules/remediation/actions/attribute.php b/modules/remediation/actions/attribute.php index 7ed3c23c..86385761 100644 --- a/modules/remediation/actions/attribute.php +++ b/modules/remediation/actions/attribute.php @@ -27,11 +27,11 @@ public function run() : ?DOMDocument { //Disable duplicates attr for image $exclusions = [ - 'alt' => ['role', 'title'], - 'role' => ['alt', 'title'] + 'alt' => [ 'role', 'title' ], + 'role' => [ 'alt', 'title' ], ]; - if ( isset( $exclusions[$this->data['attribute_name']] ) ) { - foreach ( $exclusions[$this->data['attribute_name']] as $attr_to_remove ) { + if ( isset( $exclusions[ $this->data['attribute_name'] ] ) ) { + foreach ( $exclusions[ $this->data['attribute_name'] ] as $attr_to_remove ) { $element_node->removeAttribute( $attr_to_remove ); } } diff --git a/modules/remediation/actions/replace.php b/modules/remediation/actions/replace.php index f9f32105..d785e313 100644 --- a/modules/remediation/actions/replace.php +++ b/modules/remediation/actions/replace.php @@ -24,19 +24,19 @@ public function run() : ?DOMDocument { $outer_html = $this->dom->saveHTML( $element_node ); - if ( strpos( $outer_html, $this->data['find'] ) === false ) { + if ( stripos( $outer_html, $this->data['find'] ) === false ) { return $this->dom; } - $updated_html = str_replace( $this->data['find'], $this->data['replace'], $outer_html ); + $updated_html = str_ireplace( $this->data['find'], $this->data['replace'], $outer_html ); if ( $updated_html === $outer_html ) { return $this->dom; } - $tmp_dom = new DOMDocument('1.0', 'UTF-8'); + $tmp_dom = new DOMDocument( '1.0', 'UTF-8' ); $tmp_dom->loadHTML( - mb_convert_encoding($updated_html, 'HTML-ENTITIES', 'UTF-8'), + mb_convert_encoding( $updated_html, 'HTML-ENTITIES', 'UTF-8' ), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOERROR | LIBXML_NOWARNING ); diff --git a/modules/remediation/actions/styles.php b/modules/remediation/actions/styles.php new file mode 100644 index 00000000..c709f0e8 --- /dev/null +++ b/modules/remediation/actions/styles.php @@ -0,0 +1,27 @@ +use_frontend = true; + } + + public function run() : ?DOMDocument { + return $this->dom; + } +} diff --git a/modules/remediation/assets/js/actions/replace.js b/modules/remediation/assets/js/actions/replace.js index 255925bd..d51f33c5 100644 --- a/modules/remediation/assets/js/actions/replace.js +++ b/modules/remediation/assets/js/actions/replace.js @@ -1,6 +1,18 @@ import { RemediationBase } from './base'; export class ReplaceRemediation extends RemediationBase { + replaceIgnoreCase(outerHtml, find, replace, lowerOuterHTML, lowerFind) { + const index = lowerOuterHTML.indexOf(lowerFind); + if (index === -1) { + return outerHtml; + } + return ( + outerHtml.substring(0, index) + + replace + + outerHtml.substring(index + find.length) + ); + } + run() { const { xpath, find, replace } = this.data; const el = this.getElementByXPath(xpath); @@ -11,13 +23,24 @@ export class ReplaceRemediation extends RemediationBase { if (typeof find !== 'string' || typeof replace !== 'string') { return false; } - if (!outerHTML.includes(find)) { + const lowerOuterHTML = outerHTML.toLowerCase(); + const lowerFind = find.toLowerCase(); + if (!lowerOuterHTML.includes(lowerFind)) { return false; } - const updatedHTML = outerHTML.replace(find, replace); + + const updatedHTML = this.replaceIgnoreCase( + outerHTML, + find, + replace, + lowerOuterHTML, + lowerFind, + ); + if (updatedHTML === outerHTML) { return false; } + // Create a temporary container to parse the HTML string const tmp = document.createElement('div'); tmp.innerHTML = updatedHTML; diff --git a/modules/remediation/assets/js/actions/styles.js b/modules/remediation/assets/js/actions/styles.js new file mode 100644 index 00000000..74d3fe39 --- /dev/null +++ b/modules/remediation/assets/js/actions/styles.js @@ -0,0 +1,66 @@ +import { RemediationBase } from './base'; + +export class StylesRemediation extends RemediationBase { + constructor(dom, data) { + super(dom, data); + + this.maybeAddStyleTag(); + } + + maybeAddStyleTag() { + let node = this.dom.querySelector('style#ea11y-remediation-styles'); + + if (!node) { + node = this.dom.createElement('style'); + node.id = 'ea11y-remediation-styles'; + + this.dom.body.appendChild(node); + } + } + + getStyleTag() { + return this.dom.querySelector('style#ea11y-remediation-styles'); + } + + isValidCSS(cssText) { + try { + // Basic checks for common malicious patterns + if (!cssText || typeof cssText !== 'string') { + return false; + } + + // Check for basic CSS structure and disallow dangerous patterns + const dangerousPatterns = [ + /@import/i, + /javascript:/i, + /expression\s*\(/i, + /behavior\s*:/i, + /binding\s*:/i, + /-moz-binding/i, + ]; + + if (dangerousPatterns.some((pattern) => pattern.test(cssText))) { + return false; + } + + // More comprehensive CSS structure validation + const cssRegex = /^[\s\S]*\{\s*[\s\S]+:\s*[\s\S]+;\s*\}[\s\S]*$/; + return cssRegex.test(cssText.replace(/\s+/g, ' ').trim()); + } catch (e) { + return false; + } + } + + run() { + const tag = this.getStyleTag(); + + if (!tag) { + return false; + } + + if (this.isValidCSS(this.data.rule)) { + tag.innerText += this.data.rule; + } + return true; + } +} diff --git a/modules/remediation/assets/js/module.js b/modules/remediation/assets/js/module.js index 7efa49f8..e962313f 100644 --- a/modules/remediation/assets/js/module.js +++ b/modules/remediation/assets/js/module.js @@ -1,6 +1,7 @@ import { AttributeRemediation } from './actions/attribute'; import { ElementRemediation } from './actions/element'; import { ReplaceRemediation } from './actions/replace'; +import { StylesRemediation } from './actions/styles'; class RemediationRunner { constructor(remediations) { @@ -9,8 +10,10 @@ class RemediationRunner { attribute: AttributeRemediation, element: ElementRemediation, replace: ReplaceRemediation, + styles: StylesRemediation, }; this.checkTimeout = null; + this.runAll(); } @@ -24,6 +27,7 @@ class RemediationRunner { runRemediation(remediation) { const type = (remediation.type || '').toLowerCase(); const Handler = this.classMap[type]; + if (Handler) { try { return new Handler(document, remediation).run(); diff --git a/modules/remediation/classes/utils.php b/modules/remediation/classes/utils.php index f09e3648..ecf5053e 100644 --- a/modules/remediation/classes/utils.php +++ b/modules/remediation/classes/utils.php @@ -3,17 +3,36 @@ namespace EA11y\Modules\Remediation\Classes; use EA11y\Modules\Remediation\Components\Cache_Cleaner; +use WP_Post; class Utils { /** * get current page url */ public static function get_current_page_url(): ?string { + global $post; + if ( self::is_draft( $post ) ) { + return self::build_draft_url( $post ); + } $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; $path = wp_parse_url( $request_uri, PHP_URL_PATH ); // removes query string return rtrim( home_url( $path ), '/' ); } + public static function is_draft( $post ): bool { + return $post instanceof WP_Post && in_array( $post->post_status, [ 'draft', 'pending', 'auto-draft' ], true ); + } + + public static function build_draft_url( $post ): string { + $my_post = clone $post; + $my_post->post_status = 'publish'; + $my_post->post_name = sanitize_title( + $my_post->post_name ? $my_post->post_name : $my_post->post_title, + $my_post->ID + ); + return rtrim( get_permalink( $my_post ), '/' ); + } + public static function get_current_page_title() { global $post; @@ -71,7 +90,7 @@ public static function get_current_object_type() : string { if ( $wp_query->is_singular() ) { if ( $wp_query->is_single() ) { - return $wp_query->query_vars['post_type'] ?? 'unknown'; + return get_post_type( $wp_query->get_queried_object_id() ) ?? 'unknown'; } elseif ( $wp_query->is_page() ) { return 'page'; } elseif ( $wp_query->is_attachment() ) { diff --git a/modules/remediation/components/remediation-runner.php b/modules/remediation/components/remediation-runner.php index d3c4a028..9fa99f42 100644 --- a/modules/remediation/components/remediation-runner.php +++ b/modules/remediation/components/remediation-runner.php @@ -30,12 +30,116 @@ public function get_remediation_classes() : array { 'ATTRIBUTE' => 'Attribute', 'ELEMENT' => 'Element', 'REPLACE' => 'Replace', + 'STYLES' => 'Styles', ] ); } return $classes; } + /** + * Detect AJAX requests that go through template_redirect hook + * + * Only detects frontend AJAX requests that would interfere with template_redirect, + * not admin-ajax.php requests which bypass the main query cycle. + * + * @return bool True if a template_redirect-affecting AJAX request is detected + */ + private function is_template_redirect_ajax_request(): bool { + global $wp_query; + + // Skip admin-ajax.php requests - they don't go through template_redirect + $request_uri = $_SERVER['REQUEST_URI'] ?? ''; + if ( strpos( $request_uri, '/wp-admin/admin-ajax.php' ) !== false ) { + return false; + } + + // WooCommerce frontend AJAX (wc-ajax parameter) + // These requests go through the main query cycle and template_redirect + if ( ! empty( $_REQUEST['wc-ajax'] ) ) { + return true; + } + + // Check if WP_Query has wc-ajax set (WooCommerce frontend AJAX) + if ( is_object( $wp_query ) && $wp_query->get( 'wc-ajax' ) ) { + return true; + } + + // WooCommerce AJAX constant for frontend requests + if ( defined( 'WC_DOING_AJAX' ) && constant( 'WC_DOING_AJAX' ) ) { + return true; + } + + // REST API requests that go through template_redirect + if ( defined( 'REST_REQUEST' ) && constant( 'REST_REQUEST' ) ) { + return true; + } + + // Check URL patterns for REST API (these go through template_redirect) + if ( strpos( $request_uri, '/wp-json/' ) !== false || + strpos( $request_uri, '?rest_route=' ) !== false ) { + return true; + } + + // WooCommerce Store API (frontend cart/checkout AJAX) + if ( strpos( $request_uri, '/wc/store/' ) !== false ) { + return true; + } + + // Elementor frontend AJAX/preview that affects template loading + if ( ! empty( $_REQUEST['elementor-preview'] ) || + ! empty( $_GET['elementor-preview'] ) ) { + return true; + } + + // Check for AJAX header on frontend requests (not admin) + // Only if it's not an admin request and has AJAX header + if ( ! is_admin() && + ! empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && + strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) === 'xmlhttprequest' ) { + + // Additional check: make sure it's not a heartbeat or other admin request + $action = $_REQUEST['action'] ?? ''; + if ( $action !== 'heartbeat' && strpos( $action, 'wp_ajax_' ) !== 0 ) { + return true; + } + } + + // Custom AJAX parameters that indicate frontend AJAX + $frontend_ajax_params = [ + 'ajax_request', + 'is_ajax', + 'doing_ajax' + ]; + + foreach ( $frontend_ajax_params as $param ) { + if ( ! empty( $_REQUEST[ $param ] ) ) { + return true; + } + } + + // Query string patterns for frontend AJAX + $query_string = $_SERVER['QUERY_STRING'] ?? ''; + $frontend_ajax_patterns = [ + 'ajax=true', + 'is_ajax=1', + 'ajax_request=1' + ]; + + foreach ( $frontend_ajax_patterns as $pattern ) { + if ( strpos( $query_string, $pattern ) !== false ) { + return true; + } + } + + return false; + } + private function should_run_remediation(): bool { + // Skip remediation during template_redirect AJAX requests + if ( $this->is_template_redirect_ajax_request() ) { + return false; + } + try { $current_url = Utils::get_current_page_url(); $this->page = new Page_Entry([ diff --git a/modules/remediation/database/remediation-entry.php b/modules/remediation/database/remediation-entry.php index a009a963..eef9dc36 100644 --- a/modules/remediation/database/remediation-entry.php +++ b/modules/remediation/database/remediation-entry.php @@ -48,9 +48,13 @@ public function create( string $id = 'id' ) { * * @param string $by * @param string $by_value + * @param string|null $group */ - public static function remove( string $by, string $by_value ) { - $where = [ + public static function remove( string $by, string $by_value, string $group = null ) { + $where = $group ? [ + $by => $by_value, + 'group' => $group, + ] : [ $by => $by_value, ]; Remediation_Table::delete( $where ); @@ -105,11 +109,15 @@ public static function get_all_remediations( int $period ) : array { * @param string $by * @param string $by_value * @param bool $status + * @param string|null $group * * @return void */ - public static function update_remediations_status( string $by, string $by_value, bool $status ): void { - $where = [ + public static function update_remediations_status( string $by, string $by_value, bool $status, string $group = null ): void { + $where = $group ? [ + $by => $by_value, + 'group' => $group, + ] : [ $by => $by_value, ]; diff --git a/modules/remediation/rest/items.php b/modules/remediation/rest/items.php index 6bd443be..3721160f 100644 --- a/modules/remediation/rest/items.php +++ b/modules/remediation/rest/items.php @@ -68,8 +68,9 @@ public function PATCH( $request ) { $url = esc_url( $request->get_param( 'url' ) ); $active = filter_var( $request->get_param( 'active' ), FILTER_VALIDATE_BOOLEAN ); + $group = sanitize_text_field( $request->get_param( 'group' ) ); - Remediation_Entry::update_remediations_status( Remediation_Table::URL, $url, $active ); + Remediation_Entry::update_remediations_status( Remediation_Table::URL, $url, $active, $group ); Page_Entry::clear_cache( $url ); return $this->respond_success_json( [ @@ -97,7 +98,8 @@ public function DELETE( $request ) { } $url = esc_url( $request->get_param( 'url' ) ); - Remediation_Entry::remove( Remediation_Table::URL, $url ); + $group = sanitize_text_field( $request->get_param( 'group' ) ); + Remediation_Entry::remove( Remediation_Table::URL, $url, $group ); Page_Entry::clear_cache( $url ); return $this->respond_success_json( [ diff --git a/modules/remediation/rest/register.php b/modules/remediation/rest/register.php index 70c5155f..be5d5cdb 100644 --- a/modules/remediation/rest/register.php +++ b/modules/remediation/rest/register.php @@ -75,6 +75,12 @@ public function POST( $request ) { $page->save(); } + if ( is_wp_error( $response ) && str_contains( $response->get_error_message(), 'Quota exceeded' ) ) { + return $this->respond_error_json( [ + 'message' => 'Quota exceeded', + ] ); + } + if ( ! $page->exists() || is_wp_error( $response ) ) { return $this->respond_error_json( [ 'message' => 'Failed to register page', diff --git a/modules/scanner/assets/js/app.js b/modules/scanner/assets/js/app.js index c8c17d37..9e6c3eda 100644 --- a/modules/scanner/assets/js/app.js +++ b/modules/scanner/assets/js/app.js @@ -17,7 +17,8 @@ import { ManualLayout, RemediationLayout, } from '@ea11y-apps/scanner/layouts'; -import { StyledPaper } from '@ea11y-apps/scanner/styles/app.styles'; +import { ColorContrastLayout } from '@ea11y-apps/scanner/layouts/color-contrast-layout'; +import { AppContainer } from '@ea11y-apps/scanner/styles/app.styles'; import { removeExistingFocus } from '@ea11y-apps/scanner/utils/focus-on-element'; import { useEffect } from '@wordpress/element'; @@ -30,6 +31,7 @@ const App = () => { openedBlock, isManage, isError, + quotaExceeded, loading, } = useScannerWizardContext(); @@ -51,20 +53,20 @@ const App = () => { }, [showResolvedMessage]); useEffect(() => { - if (!PAGE_QUOTA_LIMIT) { + if (!PAGE_QUOTA_LIMIT || quotaExceeded) { mixpanelService.sendEvent(mixpanelEvents.upgradeSuggestionViewed, { current_plan: window.ea11yScannerData?.planData?.plan?.name, action_trigger: 'scan_triggered', feature_locked: 'multi-page scan', }); } - }, [PAGE_QUOTA_LIMIT]); + }, [PAGE_QUOTA_LIMIT, quotaExceeded]); const getBlock = () => { if (!window.ea11yScannerData?.isConnected) { return ; } - if (!PAGE_QUOTA_LIMIT) { + if (!PAGE_QUOTA_LIMIT || quotaExceeded) { return ; } if (isError) { @@ -81,19 +83,23 @@ const App = () => { return ; case BLOCKS.altText: return ; + case BLOCKS.colorContrast: + return ; default: return isManage ? : ; } }; return ( - + }>
- {showResolvedMessage ? : getBlock()} + + {showResolvedMessage && !isManage ? : getBlock()} + -
+ ); }; diff --git a/modules/scanner/assets/js/components/alt-text-form/index.js b/modules/scanner/assets/js/components/alt-text-form/index.js index c60b51d3..43964e55 100644 --- a/modules/scanner/assets/js/components/alt-text-form/index.js +++ b/modules/scanner/assets/js/components/alt-text-form/index.js @@ -21,11 +21,8 @@ import { ImagePreview } from '@ea11y-apps/scanner/components/alt-text-form/image import { UpgradeContent } from '@ea11y-apps/scanner/components/upgrade-info-tip/upgrade-content'; import { AI_QUOTA_LIMIT, IS_AI_ENABLED } from '@ea11y-apps/scanner/constants'; import { useAltTextForm } from '@ea11y-apps/scanner/hooks/use-alt-text-form'; -import { - StyledBox, - StyledLabel, -} from '@ea11y-apps/scanner/styles/alt-text-form.styles'; -import { StyledAlert } from '@ea11y-apps/scanner/styles/app.styles'; +import { StyledLabel } from '@ea11y-apps/scanner/styles/alt-text-form.styles'; +import { StyledAlert, StyledBox } from '@ea11y-apps/scanner/styles/app.styles'; import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; import { __ } from '@wordpress/i18n'; @@ -35,6 +32,7 @@ export const AltTextForm = ({ items, current, setCurrent }) => { data, loadingAiText, isSubmitDisabled, + loading, handleChange, handleCheck, handleSubmit, @@ -187,6 +185,7 @@ export const AltTextForm = ({ items, current, setCurrent }) => { variant="contained" color="info" fullWidth + loading={loading} disabled={isSubmitDisabled} onClick={onSubmit} > diff --git a/modules/scanner/assets/js/components/block-button/index.js b/modules/scanner/assets/js/components/block-button/index.js index eea020ce..2b24ce66 100644 --- a/modules/scanner/assets/js/components/block-button/index.js +++ b/modules/scanner/assets/js/components/block-button/index.js @@ -9,15 +9,8 @@ import { StyledButton, StyledButtonContainer, } from '@ea11y-apps/scanner/styles/app.styles'; -import { __, sprintf } from '@wordpress/i18n'; -export const BlockButton = ({ - title, - count, - block, - total, - isManage = false, -}) => { +export const BlockButton = ({ title, count, block }) => { const { setOpenedBlock, isResolved } = useScannerWizardContext(); const handleClick = () => { @@ -26,12 +19,11 @@ export const BlockButton = ({ page_url: window.ea11yScannerData?.pageData?.url, issue_count: count, category_name: title, - source: isManage ? 'remediation' : 'assistant', + source: 'assistant', }); }; - const resolved = !isManage && (count === 0 || isResolved(block)); - const showChip = !isManage && !resolved; + const resolved = count === 0 || isResolved(block); return ( - {title} - {showChip && ( + + {title} + + + {!resolved && ( )} + {resolved && } - {isManage && ( - 0 ? 'info' : 'default'} - variant="standard" - size="tiny" - disabled={count === 0} - /> - )} ); @@ -76,6 +58,4 @@ BlockButton.propTypes = { title: PropTypes.string.isRequired, count: PropTypes.number.isRequired, block: PropTypes.string.isRequired, - total: PropTypes.number, - isManage: PropTypes.bool, }; diff --git a/modules/scanner/assets/js/components/block-button/manage-button.js b/modules/scanner/assets/js/components/block-button/manage-button.js new file mode 100644 index 00000000..0fa5d259 --- /dev/null +++ b/modules/scanner/assets/js/components/block-button/manage-button.js @@ -0,0 +1,80 @@ +import Chip from '@elementor/ui/Chip'; +import Typography from '@elementor/ui/Typography'; +import PropTypes from 'prop-types'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; +import { DeleteButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/delete-button'; +import { DisableButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/disable-button'; +import { EnableButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/enable-button'; +import { BLOCKS } from '@ea11y-apps/scanner/constants'; +import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; +import { + ActionButton, + ManageButtonGroup, + ManageButtonWrap, +} from '@ea11y-apps/scanner/styles/app.styles'; +import { __, sprintf } from '@wordpress/i18n'; + +export const ManageButton = ({ title, count, block }) => { + const { sortedRemediation, setOpenedBlock } = useScannerWizardContext(); + + const handleClick = () => { + setOpenedBlock(block); + mixpanelService.sendEvent(mixpanelEvents.categoryClicked, { + page_url: window.ea11yScannerData?.pageData?.url, + issue_count: count, + category_name: title, + source: 'remediation', + }); + }; + + const total = sortedRemediation[block].length; + const disabled = block === BLOCKS.colorContrast || block === BLOCKS.altText; + const isAllDisabled = + sortedRemediation[block]?.length === + sortedRemediation[block]?.filter( + (remediation) => !Number(remediation.active), + )?.length; + + return ( + + + + {title} + + + 0 ? 'info' : 'default'} + variant="standard" + size="tiny" + disabled={count === 0} + /> + + {isAllDisabled ? ( + + ) : ( + + )} + + + + ); +}; + +ManageButton.propTypes = { + title: PropTypes.string.isRequired, + count: PropTypes.number.isRequired, + block: PropTypes.string.isRequired, +}; diff --git a/modules/scanner/assets/js/components/color-contrast-form/color-set.js b/modules/scanner/assets/js/components/color-contrast-form/color-set.js new file mode 100644 index 00000000..9bee1c94 --- /dev/null +++ b/modules/scanner/assets/js/components/color-contrast-form/color-set.js @@ -0,0 +1,152 @@ +import RotateIcon from '@elementor/icons/RotateIcon'; +import Box from '@elementor/ui/Box'; +import Button from '@elementor/ui/Button'; +import IconButton from '@elementor/ui/IconButton'; +import InputAdornment from '@elementor/ui/InputAdornment'; +import Slider from '@elementor/ui/Slider'; +import TextField from '@elementor/ui/TextField'; +import Tooltip from '@elementor/ui/Tooltip'; +import Typography from '@elementor/ui/Typography'; +import { styled } from '@elementor/ui/styles'; +import { UnstableColorPicker } from '@elementor/ui/unstable'; +import PropTypes from 'prop-types'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; +import { SunIcon, SunOffIcon } from '@ea11y-apps/scanner/images'; +import { hexToHsl, hslToHex } from '@ea11y-apps/scanner/utils/convert-colors'; +import { useEffect, useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +export const ColorSet = ({ title, color, initialColor, setColor, area }) => { + const [selectedColor, setSelectedColor] = useState(initialColor); + const hslColor = hexToHsl(color); + + useEffect(() => { + setSelectedColor(initialColor); + }, [initialColor]); + + const sendEvent = (component, event = null) => { + mixpanelService.sendEvent(event ?? mixpanelEvents.contrastColorChanged, { + area, + component, + }); + }; + + const resetColor = () => { + setColor(initialColor); + sendEvent('reset', mixpanelEvents.contrastResetClicked); + }; + + const onColorChange = (changedColor) => { + setSelectedColor(changedColor); + setColor(changedColor); + sendEvent('color-picker'); + }; + + const onLightnessChange = (event, value) => { + const raw = event?.target?.value || value; + // Allow only digits + if (raw && !/^\d{1,2}$|^100$/.test(raw)) { + return; + } + + const num = raw && !isNaN(raw) ? parseInt(raw, 10) : 0; + + if (num >= 0 && num <= 100) { + const initialHslColor = hexToHsl(selectedColor); + const updatedColor = hslToHex({ + ...initialHslColor, + l: num, + }); + setColor(updatedColor); + sendEvent('slider'); + } + }; + + return ( + + + {title} + + + + + + + + + ), + }} + /> + + + {color !== initialColor ? ( + + + + ) : ( + + )} + + + + ); +}; + +const StyledColorSet = styled(Box)` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(1)}; +`; + +ColorSet.propTypes = { + title: PropTypes.string.isRequired, + color: PropTypes.string.isRequired, + initialColor: PropTypes.string.isRequired, + setColor: PropTypes.func.isRequired, + area: PropTypes.string.isRequired, +}; diff --git a/modules/scanner/assets/js/components/color-contrast-form/index.js b/modules/scanner/assets/js/components/color-contrast-form/index.js new file mode 100644 index 00000000..28a674cc --- /dev/null +++ b/modules/scanner/assets/js/components/color-contrast-form/index.js @@ -0,0 +1,155 @@ +import Alert from '@elementor/ui/Alert'; +import AlertTitle from '@elementor/ui/AlertTitle'; +import Box from '@elementor/ui/Box'; +import Button from '@elementor/ui/Button'; +import Divider from '@elementor/ui/Divider'; +import Typography from '@elementor/ui/Typography'; +import PropTypes from 'prop-types'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; +import { ColorSet } from '@ea11y-apps/scanner/components/color-contrast-form/color-set'; +import { ParentSelector } from '@ea11y-apps/scanner/components/color-contrast-form/parent-selector'; +import { BLOCKS } from '@ea11y-apps/scanner/constants'; +import { useColorContrastForm } from '@ea11y-apps/scanner/hooks/use-color-contrast-form'; +import { StyledBox } from '@ea11y-apps/scanner/styles/app.styles'; +import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; +import { + checkContrastAA, + isLargeText, +} from '@ea11y-apps/scanner/utils/calc-color-ratio'; +import { __, sprintf } from '@wordpress/i18n'; + +export const ColorContrastForm = ({ items, current, setCurrent }) => { + const item = items[current]; + const { + color, + background, + parents, + resolved, + backgroundChanged, + loading, + changeColor, + changeBackground, + setParentSmaller, + setParentLarger, + onSubmit, + } = useColorContrastForm({ + item, + current, + setCurrent, + }); + + const isPossibleToResolve = item.messageArgs[3] && item.messageArgs[4]; + + const passRatio = isLargeText(item.node) ? '3:1' : '4.5:1'; + + const colorData = + color && background + ? checkContrastAA(color, background, item.node) + : { + ratio: item.messageArgs[0], + passesAA: false, + }; + + const handleSubmit = async () => { + await onSubmit(); + mixpanelService.sendEvent(mixpanelEvents.applyFixButtonClicked, { + fix_method: 'color contrast', + issue_type: item.message, + current_contrast_ratio: colorData.ratio, + background_level: parents.length, + category_name: BLOCKS.colorContrast, + page_url: window.ea11yScannerData?.pageData?.url, + }); + }; + + return ( + + + {!isPossibleToResolve ? ( + <> + + + {__('What’s the issue?', 'pojo-accessibility')} + + + {__( + 'Adjust the text or background lightness until the indicator shows an accessible level.', + 'pojo-accessibility', + )} + + + + + {__('How to resolve?', 'pojo-accessibility')} + + + {sprintf( + // Translators: %s - color ratio + __( + 'To meet accessibility standards, update the text or background color to reach a contrast ratio of at least %s', + 'pojo-accessibility', + ), + passRatio, + )} + + + + ) : ( + <> + + {__( + 'Adjust the text or background lightness until the indicator shows an accessible level.', + 'pojo-accessibility', + )} + + + + + )} + + {backgroundChanged && ( + + )} + + + {__('Contrast level:', 'pojo-accessibility')} + + {colorData.ratio} + + {isPossibleToResolve && ( + + )} + + ); +}; + +ColorContrastForm.propTypes = { + items: PropTypes.arrayOf(scannerItem).isRequired, + current: PropTypes.number.isRequired, + setCurrent: PropTypes.func.isRequired, +}; diff --git a/modules/scanner/assets/js/components/color-contrast-form/parent-selector.js b/modules/scanner/assets/js/components/color-contrast-form/parent-selector.js new file mode 100644 index 00000000..a3e8e89b --- /dev/null +++ b/modules/scanner/assets/js/components/color-contrast-form/parent-selector.js @@ -0,0 +1,99 @@ +import MinusIcon from '@elementor/icons/MinusIcon'; +import PlusIcon from '@elementor/icons/PlusIcon'; +import Box from '@elementor/ui/Box'; +import IconButton from '@elementor/ui/IconButton'; +import Tooltip from '@elementor/ui/Tooltip'; +import Typography from '@elementor/ui/Typography'; +import { styled } from '@elementor/ui/styles'; +import PropTypes from 'prop-types'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; +import { COLOR_CONTRAST_SELECTORS_COUNT } from '@ea11y-apps/scanner/constants'; +import { useEffect } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +export const ParentSelector = ({ + parents, + setParentSmaller, + setParentLarger, +}) => { + useEffect(() => { + mixpanelService.sendEvent(mixpanelEvents.backgroundAdaptorTriggered); + }, []); + + const selected = Math.max(0, COLOR_CONTRAST_SELECTORS_COUNT - parents.length); + const smallerEnabled = parents.length > 1; + const biggerEnabled = parents.length > 0 && parents.at(-1) !== '/html'; + + return ( + + + {__('Background area', 'pojo-accessibility')} + + + + {smallerEnabled ? ( + + + + ) : ( + + )} + + + {[...Array(COLOR_CONTRAST_SELECTORS_COUNT)].map((_, i) => { + const size = 16 + (COLOR_CONTRAST_SELECTORS_COUNT - 1 - i) * 16; + const filled = i === selected; + return ; + })} + + + {biggerEnabled ? ( + + + + ) : ( + + )} + + + + ); +}; + +const ParentIndicator = styled(Box)` + position: relative; + width: 80px; + height: 80px; + display: flex; + align-items: center; + justify-content: center; +`; + +const Square = styled(Box)` + position: absolute; + width: ${({ size }) => size}px; + height: ${({ size }) => size}px; + box-sizing: border-box; + border: ${({ filled }) => (filled ? '1px solid #000' : '1px dashed #000')}; + background-color: ${({ filled }) => (filled ? '#93C5FD' : 'transparent')}; +`; + +ParentSelector.propTypes = { + parents: PropTypes.arrayOf(PropTypes.string).isRequired, + setParentSmaller: PropTypes.func.isRequired, + setParentLarger: PropTypes.func.isRequired, +}; diff --git a/modules/scanner/assets/js/components/alt-text-navigation/index.js b/modules/scanner/assets/js/components/form-navigation/index.js similarity index 54% rename from modules/scanner/assets/js/components/alt-text-navigation/index.js rename to modules/scanner/assets/js/components/form-navigation/index.js index 002820dc..579b053e 100644 --- a/modules/scanner/assets/js/components/alt-text-navigation/index.js +++ b/modules/scanner/assets/js/components/form-navigation/index.js @@ -1,63 +1,72 @@ import ChevronLeftIcon from '@elementor/icons/ChevronLeftIcon'; import ChevronRightIcon from '@elementor/icons/ChevronRightIcon'; import Box from '@elementor/ui/Box'; +import Divider from '@elementor/ui/Divider'; import IconButton from '@elementor/ui/IconButton'; import Typography from '@elementor/ui/Typography'; import { styled } from '@elementor/ui/styles'; import PropTypes from 'prop-types'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { isRTL } from '@ea11y-apps/scanner/constants'; +import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { __, sprintf } from '@wordpress/i18n'; -export const AltTextNavigation = ({ total, current, setCurrent }) => { +export const FormNavigation = ({ total, current, setCurrent }) => { + const { openedBlock } = useScannerWizardContext(); const previous = current - 1; const next = current + 1; const navigate = (index, direction) => () => { setCurrent(index); mixpanelService.sendEvent(mixpanelEvents.navigationImageClicked, { direction, + category: openedBlock, }); }; return ( - - - - - - - {sprintf( - // Translators: %1$s - current, %2$s - total - __('%1$s of %2$s issues', 'pojo-accessibility'), - current + 1, - total, - )} - - - - - - + + + + + + + + + {sprintf( + // Translators: %1$s - current, %2$s - total + __('%1$s of %2$s issues', 'pojo-accessibility'), + current + 1, + total, + )} + + + + + + + ); }; -const StyledBox = styled(Box)` +const Navigation = styled(Box)` position: absolute; bottom: 0; left: 0; width: 100%; - padding-block: ${({ theme }) => theme.spacing(2)}; - +`; +const StyledBox = styled(Box)` display: flex; justify-content: center; + padding-block: ${({ theme }) => theme.spacing(2)}; `; + const StyledNavigation = styled(Box)` display: flex; justify-content: space-between; @@ -69,7 +78,7 @@ const StyledIconButton = styled(IconButton)` ${isRTL ? 'transform: rotate(180deg)' : ''} `; -AltTextNavigation.propTypes = { +FormNavigation.propTypes = { total: PropTypes.number.isRequired, current: PropTypes.number.isRequired, setCurrent: PropTypes.func.isRequired, diff --git a/modules/scanner/assets/js/components/header/breadcrumbs.js b/modules/scanner/assets/js/components/header/breadcrumbs.js index 3601e3fb..08d3ac0c 100644 --- a/modules/scanner/assets/js/components/header/breadcrumbs.js +++ b/modules/scanner/assets/js/components/header/breadcrumbs.js @@ -54,12 +54,15 @@ export const Breadcrumbs = () => { > + - + {BLOCK_TITLES[openedBlock]} + {BLOCK_INFO[openedBlock] && ( { }); }; - const onRunNewScan = () => { + const onRescan = () => { runNewScan(); - sendOnClickEvent('New Scan'); + sendOnClickEvent('Rescan'); }; const goToManagement = () => { @@ -61,12 +61,14 @@ export const DropdownMenu = () => { > +
{ }} disablePortal > - + - {__('New Scan', 'pojo-accessibility')} + + {__('Rescan', 'pojo-accessibility')} + {!remediations.length ? ( { ], }} > - + - {__('Manage AI fixes', 'pojo-accessibility')} + {__('Manage fixes', 'pojo-accessibility')} @@ -117,12 +121,13 @@ export const DropdownMenu = () => { onClick={goToManagement} disabled={isManage} selected={isManage} + dense > - {__('Manage AI fixes', 'pojo-accessibility')} + {__('Manage fixes', 'pojo-accessibility')} )} @@ -133,6 +138,7 @@ export const DropdownMenu = () => { target="_blank" rel="noreferrer" onClick={() => sendOnClickEvent('View subscription')} + dense > diff --git a/modules/scanner/assets/js/components/header/index.js b/modules/scanner/assets/js/components/header/index.js index d02c384e..cf51ec6c 100644 --- a/modules/scanner/assets/js/components/header/index.js +++ b/modules/scanner/assets/js/components/header/index.js @@ -88,9 +88,10 @@ export const Header = () => { - + {window?.ea11yScannerData?.pageData?.title} + {showChip && ( { {isManage ? ( <> - - {__('Manage AI fixes', 'pojo-accessibility')} + + + {__('Manage fixes', 'pojo-accessibility')} ) : ( <> - + {__('Accessibility Assistant', 'pojo-accessibility')} { + {showMainBlock && ( {isMainHeader ? ( @@ -176,6 +179,12 @@ const StyledCard = styled(Card)` `; const StyledTitle = styled(Typography)` + font-size: 16px; + font-weight: 500; + line-height: 130%; + letter-spacing: 0.15px; + margin: 0; + .MuiChip-root { margin-inline-start: ${({ theme }) => theme.spacing(1)}; diff --git a/modules/scanner/assets/js/components/manage-list/index.js b/modules/scanner/assets/js/components/manage-list/index.js index 6fe56a47..34121e34 100644 --- a/modules/scanner/assets/js/components/manage-list/index.js +++ b/modules/scanner/assets/js/components/manage-list/index.js @@ -1,4 +1,4 @@ -import { BlockButton } from '@ea11y-apps/scanner/components/block-button'; +import { ManageButton } from '@ea11y-apps/scanner/components/block-button/manage-button'; import { BLOCK_TITLES, BLOCKS } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { StyledBlockButtonsBox } from '@ea11y-apps/scanner/styles/app.styles'; @@ -18,13 +18,11 @@ export const ManageList = () => { 0; return ( - ); })} diff --git a/modules/scanner/assets/js/components/manage-remediation-buttons/delete-button.js b/modules/scanner/assets/js/components/manage-remediation-buttons/delete-button.js new file mode 100644 index 00000000..5d2e0213 --- /dev/null +++ b/modules/scanner/assets/js/components/manage-remediation-buttons/delete-button.js @@ -0,0 +1,51 @@ +import TrashIcon from '@elementor/icons/TrashIcon'; +import Button from '@elementor/ui/Button'; +import IconButton from '@elementor/ui/IconButton'; +import { DeleteRemediationModal } from '@ea11y-apps/scanner/components/delete-remediation-modal'; +import { useManageActions } from '@ea11y-apps/scanner/hooks/use-manage-actions'; +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; + +export const DeleteButton = ({ group }) => { + const { deleteAllRemediationForPage } = useManageActions(); + const [showDeleteModal, setShowDeleteModal] = useState(false); + + const toggleDeleteModal = () => setShowDeleteModal(!showDeleteModal); + + const onDeleteRemediation = async () => { + setShowDeleteModal(false); + await deleteAllRemediationForPage(group); + }; + + return ( + <> + {group ? ( + + + + ) : ( + + )} + + + + ); +}; diff --git a/modules/scanner/assets/js/components/manage-remediation-buttons/disable-button.js b/modules/scanner/assets/js/components/manage-remediation-buttons/disable-button.js new file mode 100644 index 00000000..f679f2ee --- /dev/null +++ b/modules/scanner/assets/js/components/manage-remediation-buttons/disable-button.js @@ -0,0 +1,29 @@ +import BanIcon from '@elementor/icons/BanIcon'; +import Button from '@elementor/ui/Button'; +import IconButton from '@elementor/ui/IconButton'; +import { useManageActions } from '@ea11y-apps/scanner/hooks/use-manage-actions'; +import { __ } from '@wordpress/i18n'; + +export const DisableButton = ({ group }) => { + const { updateAllRemediationForPage } = useManageActions(); + return group ? ( + + + + ) : ( + + ); +}; diff --git a/modules/scanner/assets/js/components/manage-remediation-buttons/enable-button.js b/modules/scanner/assets/js/components/manage-remediation-buttons/enable-button.js new file mode 100644 index 00000000..dea1bc44 --- /dev/null +++ b/modules/scanner/assets/js/components/manage-remediation-buttons/enable-button.js @@ -0,0 +1,29 @@ +import ReloadIcon from '@elementor/icons/ReloadIcon'; +import Button from '@elementor/ui/Button'; +import IconButton from '@elementor/ui/IconButton'; +import { useManageActions } from '@ea11y-apps/scanner/hooks/use-manage-actions'; +import { __ } from '@wordpress/i18n'; + +export const EnableButton = ({ group }) => { + const { updateAllRemediationForPage } = useManageActions(); + return group ? ( + + + + ) : ( + + ); +}; diff --git a/modules/scanner/assets/js/components/manage-remediation-buttons/index.js b/modules/scanner/assets/js/components/manage-remediation-buttons/index.js index f42a39ed..6aaaf80b 100644 --- a/modules/scanner/assets/js/components/manage-remediation-buttons/index.js +++ b/modules/scanner/assets/js/components/manage-remediation-buttons/index.js @@ -1,71 +1,22 @@ -import BanIcon from '@elementor/icons/BanIcon'; -import ReloadIcon from '@elementor/icons/ReloadIcon'; -import TrashIcon from '@elementor/icons/TrashIcon'; import Box from '@elementor/ui/Box'; -import Button from '@elementor/ui/Button'; import Divider from '@elementor/ui/Divider'; -import IconButton from '@elementor/ui/IconButton'; -import { DeleteRemediationModal } from '@ea11y-apps/scanner/components/delete-remediation-modal'; +import { DeleteButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/delete-button'; +import { DisableButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/disable-button'; +import { EnableButton } from '@ea11y-apps/scanner/components/manage-remediation-buttons/enable-button'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; -import { useManageActions } from '@ea11y-apps/scanner/hooks/use-manage-actions'; -import { useState } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; export const ManageRemediationButtons = () => { const { remediations } = useScannerWizardContext(); - const { updateAllRemediationForPage, deleteAllRemediationForPage } = - useManageActions(); - const [showDeleteModal, setShowDeleteModal] = useState(false); const isAllDisabled = remediations?.length === remediations?.filter((remediation) => !Number(remediation.active))?.length; - const toggleDeleteModal = () => setShowDeleteModal(!showDeleteModal); - - const onDeleteRemediation = async () => { - setShowDeleteModal(false); - await deleteAllRemediationForPage(); - }; - return ( - - - + {isAllDisabled ? : } - {isAllDisabled ? ( - - ) : ( - - )} - + ); }; diff --git a/modules/scanner/assets/js/components/manual-fix-form/index.js b/modules/scanner/assets/js/components/manual-fix-form/index.js index da314fbe..ebc31e9b 100644 --- a/modules/scanner/assets/js/components/manual-fix-form/index.js +++ b/modules/scanner/assets/js/components/manual-fix-form/index.js @@ -15,11 +15,7 @@ import { useToastNotification } from '@ea11y-apps/global/hooks'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; import { ResolveWithAi } from '@ea11y-apps/scanner/components/manual-fix-form/resolve-with-ai'; -import { - BLOCK_TITLES, - BLOCKS, - EXCLUDE_FROM_AI, -} from '@ea11y-apps/scanner/constants'; +import { BLOCKS, EXCLUDE_FROM_AI } from '@ea11y-apps/scanner/constants'; import { uxMessaging } from '@ea11y-apps/scanner/constants/ux-messaging'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { useCopyToClipboard } from '@ea11y-apps/scanner/hooks/use-copy-to-clipboard'; @@ -32,6 +28,7 @@ import { StyledSnippet, } from '@ea11y-apps/scanner/styles/manual-fixes.styles'; import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; +import { speak } from '@wordpress/a11y'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -54,16 +51,31 @@ export const ManualFixForm = ({ item, current, setOpen }) => { const sendMixpanelEvent = (event) => { mixpanelService.sendEvent(event, { - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, issue_type: item.message, element_selector: item.path.dom, }); }; + const focusOnActive = () => { + const rootNode = document.getElementById('ea11y-scanner-wizard-widget'); + const currentItem = rootNode.shadowRoot.querySelector( + `#manual-panel-${current}`, + ); + + if (currentItem) { + currentItem.focus(); + } + }; + const handleSkip = () => { closeExample(); setOpen(current + 1); + focusOnActive(); + sendMixpanelEvent(mixpanelEvents.issueSkipped); + + speak(__('Issue skipped', 'pojo-accessibility'), 'polite'); }; const handleMarkResolved = async () => { @@ -72,7 +84,11 @@ export const ManualFixForm = ({ item, current, setOpen }) => { closeExample(); markResolved(); + focusOnActive(); + sendMixpanelEvent(mixpanelEvents.markAsResolveClicked); + + speak(__('Issue resolved', 'pojo-accessibility'), 'polite'); } catch (e) { error(__('An error occurred.', 'pojo-accessibility')); } @@ -87,10 +103,12 @@ export const ManualFixForm = ({ item, current, setOpen }) => { - + {__('What’s the issue', 'pojo-accessibility')} + { 'pojo-accessibility', )} + {uxMessaging[item.ruleId].whyItMatters} @@ -115,17 +134,21 @@ export const ManualFixForm = ({ item, current, setOpen }) => { + {uxMessaging[item.ruleId]?.whatsTheIssue ?? item.message} + - + {__('Where is it', 'pojo-accessibility')} + {item.snippet} + { + {showAIBlock && } + {uxMessaging[item.ruleId] && ( <> - + {__('How to resolve it', 'pojo-accessibility')} + {uxMessaging[item.ruleId].howToResolve} + { justifyContent="space-between" alignItems="start" > - + {__('See an example', 'pojo-accessibility')} + { - + {__('Issue:', 'pojo-accessibility')} + { > {uxMessaging[item.ruleId].seeAnExample.issue} - + + {__('Resolution:', 'pojo-accessibility')} + {uxMessaging[item.ruleId].seeAnExample.resolution.flatMap( (resolution, index) => ( { ), )} + + )} + - diff --git a/modules/scanner/assets/js/constants/index.js b/modules/scanner/assets/js/constants/index.js index 71e7aa0e..b4efd439 100644 --- a/modules/scanner/assets/js/constants/index.js +++ b/modules/scanner/assets/js/constants/index.js @@ -7,6 +7,11 @@ export const MANAGE_URL_PARAM = 'open-ea11y-manage'; export const ROOT_ID = 'ea11y-scanner-wizard-widget'; export const CURRENT_ELEMENT_CLASS = 'ea11y-scanner-current-element'; +export const COLOR_ELEMENT_CLASS = 'ea11y-scanner-color-element'; +export const BACKGROUND_ELEMENT_CLASS = 'ea11y-scanner-background-element'; +export const COLOR_CONTRAST_SELECTORS_COUNT = 5; +export const DATA_INITIAL_BG = 'data-initial-bg'; +export const DATA_INITIAL_COLOR = 'data-initial-color'; export const UPGRADE_URL = 'https://go.elementor.com/acc-free-no-AI-scanner'; export const COMPARE_PLAN_URL = 'https://go.elementor.com/acc-AI-limit-scanner'; @@ -28,7 +33,7 @@ export const PAGE_PER_PLAN = export const PAGE_QUOTA_LIMIT = window.ea11yScannerData?.planData?.scannedPages?.allowed - window.ea11yScannerData?.planData?.scannedPages?.used > - 0; + 0 || !window?.ea11yScannerData?.pageData?.unregistered; export const BLOCKS = { main: 'main', @@ -63,7 +68,7 @@ export const BLOCK_TITLES = { ), pageStructureNav: __('Page Structure & Navigation', 'pojo-accessibility'), tables: __('Tables', 'pojo-accessibility'), - colorContrast: __('Color Contrast & Style', 'pojo-accessibility'), + colorContrast: __('Color contrast', 'pojo-accessibility'), other: __('Other Accessibility Issues', 'pojo-accessibility'), }; @@ -93,7 +98,7 @@ export const BLOCK_INFO = { 'pojo-accessibility', ), colorContrast: __( - 'Choose colors with strong contrast to ensure your text is readable for everyone.', + 'Text and background lightness can hinder readability. Depending on text size, you may need to adjust the contrast level to improve accessibility.', 'pojo-accessibility', ), other: __( diff --git a/modules/scanner/assets/js/context/scanner-wizard-context.js b/modules/scanner/assets/js/context/scanner-wizard-context.js index 765d47a1..e633a512 100644 --- a/modules/scanner/assets/js/context/scanner-wizard-context.js +++ b/modules/scanner/assets/js/context/scanner-wizard-context.js @@ -1,7 +1,6 @@ import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; import { - BLOCK_TITLES, BLOCKS, INITIAL_SORTED_VIOLATIONS, MANAGE_URL_PARAM, @@ -32,6 +31,7 @@ export const ScannerWizardContext = createContext({ openedBlock: '', loading: null, isError: false, + quotaExceeded: false, isManage: false, isChanged: false, sortedViolations: INITIAL_SORTED_VIOLATIONS, @@ -72,6 +72,7 @@ export const ScannerWizardContextProvider = ({ children }) => { const [openedBlock, setOpenedBlock] = useState(BLOCKS.main); const [loading, setLoading] = useState(true); const [isError, setIsError] = useState(false); + const [quotaExceeded, setQuotaExceeded] = useState(false); const [isManage, setIsManage] = useState(false); const [isManageChanged, setIsManageChanged] = useState(false); const [altTextData, setAltTextData] = useState([]); @@ -118,13 +119,9 @@ export const ScannerWizardContextProvider = ({ children }) => { window.ea11yScannerData?.pageData?.url, ); - const filteredRemediations = items.data.filter( - (remediation) => remediation.group !== BLOCKS.altText, - ); - - const sorted = sortRemediation(filteredRemediations); + const sorted = sortRemediation(items.data); - setRemediations(filteredRemediations); + setRemediations(items.data); setSortedRemediation(sorted); } catch (error) { setIsError(true); @@ -138,7 +135,7 @@ export const ScannerWizardContextProvider = ({ children }) => { issue_type: item.message, rule_id: item.ruleId, wcag_level: item.reasonCategory.match(/\((AAA?|AA?|A)\)/)?.[1] || '', - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, }); } }; @@ -152,7 +149,7 @@ export const ScannerWizardContextProvider = ({ children }) => { window.ea11yScannerData.initialScanResult?.counts?.violation ?? 0; const violation = results?.summary?.counts?.violation >= 0 - ? Math.max(initialViolations, results?.summary?.counts?.violation) + ? results?.summary?.counts?.violation : null; const registerPage = async (data, sorted) => { @@ -168,11 +165,14 @@ export const ScannerWizardContextProvider = ({ children }) => { setAltTextData([]); setManualData(structuredClone(MANUAL_GROUPS)); setResolved( - initialViolations > data.summary?.counts?.violation - ? initialViolations - data.summary?.counts?.violation + initialViolations >= data.summary?.counts?.issuesResolved + ? data.summary?.counts?.issuesResolved : 0, ); } catch (e) { + if (e?.message === 'Quota exceeded') { + setQuotaExceeded(true); + } setIsError(true); } }; @@ -202,7 +202,10 @@ export const ScannerWizardContextProvider = ({ children }) => { const url = new URL(window.location.href); const data = await window.ace.check(document); const filtered = data.results.filter( - (item) => item.level === 'violation', + (item) => + item.level === 'violation' || + (item.ruleId === 'text_contrast_sufficient' && + item.level === 'potentialViolation'), ); const sorted = sortViolations(filtered); @@ -300,6 +303,7 @@ export const ScannerWizardContextProvider = ({ children }) => { openedBlock, loading, isError, + quotaExceeded, isManage, isChanged, sortedViolations, diff --git a/modules/scanner/assets/js/hooks/use-alt-text-form.js b/modules/scanner/assets/js/hooks/use-alt-text-form.js index 0143c009..03adecd6 100644 --- a/modules/scanner/assets/js/hooks/use-alt-text-form.js +++ b/modules/scanner/assets/js/hooks/use-alt-text-form.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { useToastNotification } from '@ea11y-apps/global/hooks'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; -import { BLOCK_TITLES, BLOCKS } from '@ea11y-apps/scanner/constants'; +import { BLOCKS } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; import { removeExistingFocus } from '@ea11y-apps/scanner/utils/focus-on-element'; @@ -23,16 +23,19 @@ export const useAltTextForm = ({ current, item }) => { setResolved, isResolved, setOpenedBlock, + updateRemediationList, } = useScannerWizardContext(); const { error } = useToastNotification(); const [loadingAiText, setLoadingAiText] = useState(false); + const [loading, setLoading] = useState(false); const [firstOpen, setFirstOpen] = useState(true); const isSubmitDisabled = (!altTextData?.[current]?.makeDecorative && !altTextData?.[current]?.altText) || - altTextData?.[current]?.resolved; + altTextData?.[current]?.resolved || + loading; useEffect(() => { if (!firstOpen && isResolved(BLOCKS.altText)) { @@ -102,6 +105,7 @@ export const useAltTextForm = ({ current, item }) => { }); await APIScanner.resolveIssue(currentScanId); + void updateRemediationList(); } catch (e) { console.warn(e); } @@ -115,7 +119,7 @@ export const useAltTextForm = ({ current, item }) => { }); if (e.target.checked) { mixpanelService.sendEvent(mixpanelEvents.markAsDecorativeSelected, { - category_name: BLOCK_TITLES[BLOCKS.altText], + category_name: BLOCKS.altText, }); } }; @@ -129,30 +133,38 @@ export const useAltTextForm = ({ current, item }) => { }; const handleSubmit = async () => { - const fixMethod = altTextData?.[current]?.apiId - ? 'AI alt-text' - : 'Manual alt-text'; - await updateAltText(item); - if (!altTextData?.[current]?.resolved) { - updateData({ resolved: true }); - setResolved(resolved + 1); - } + try { + setLoading(true); + const fixMethod = altTextData?.[current]?.apiId + ? 'AI alt-text' + : 'Manual alt-text'; + await updateAltText(item); + if (!altTextData?.[current]?.resolved) { + updateData({ resolved: true }); + setResolved(resolved + 1); + } - if (altTextData?.[current]?.apiId) { - mixpanelService.sendEvent(mixpanelEvents.aiSuggestionAccepted, { - element_selector: item.path.dom, - image_src: item.node?.src, - final_text: altTextData?.[current]?.altText, - credit_used: 1, + if (altTextData?.[current]?.apiId) { + mixpanelService.sendEvent(mixpanelEvents.aiSuggestionAccepted, { + element_selector: item.path.dom, + image_src: item.node?.src, + final_text: altTextData?.[current]?.altText, + credit_used: 1, + }); + } + mixpanelService.sendEvent(mixpanelEvents.applyFixButtonClicked, { + fix_method: altTextData?.[current]?.makeDecorative + ? 'Mark as decorative' + : fixMethod, + issue_type: item.message, + category_name: BLOCKS.altText, + page_url: window.ea11yScannerData?.pageData?.url, }); + } catch (e) { + console.error(e); + } finally { + setLoading(false); } - mixpanelService.sendEvent(mixpanelEvents.applyFixButtonClicked, { - fix_method: altTextData?.[current]?.makeDecorative - ? 'Mark as decorative' - : fixMethod, - issue_type: item.message, - category_name: BLOCK_TITLES[BLOCKS.altText], - }); }; const getPayload = async () => { @@ -169,8 +181,9 @@ export const useAltTextForm = ({ current, item }) => { issue_type: item.message, rule_id: item.ruleId, wcag_level: item.reasonCategory.match(/\((AAA?|AA?|A)\)/)?.[1] || '', - category_name: BLOCK_TITLES[BLOCKS.altText], + category_name: BLOCKS.altText, ai_text_response: text, + page_url: window.ea11yScannerData?.pageData?.url, }); }; @@ -222,6 +235,7 @@ export const useAltTextForm = ({ current, item }) => { loadingAiText, data: altTextData, isSubmitDisabled, + loading, handleCheck, handleChange, handleSubmit, diff --git a/modules/scanner/assets/js/hooks/use-color-contrast-form.js b/modules/scanner/assets/js/hooks/use-color-contrast-form.js new file mode 100644 index 00000000..185c4961 --- /dev/null +++ b/modules/scanner/assets/js/hooks/use-color-contrast-form.js @@ -0,0 +1,285 @@ +import getXPath from 'get-xpath'; +import PropTypes from 'prop-types'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; +import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; +import { + BACKGROUND_ELEMENT_CLASS, + BLOCKS, + DATA_INITIAL_BG, + DATA_INITIAL_COLOR, +} from '@ea11y-apps/scanner/constants'; +import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; +import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; +import { + focusOnElement, + removeExistingFocus, +} from '@ea11y-apps/scanner/utils/focus-on-element'; +import { getElementByXPath } from '@ea11y-apps/scanner/utils/get-element-by-xpath'; +import { getElementCSSSelector } from '@ea11y-apps/scanner/utils/get-element-css-selector'; +import { useEffect, useState } from '@wordpress/element'; + +export const useColorContrastForm = ({ item, current, setCurrent }) => { + const { + openedBlock, + manualData, + resolved: resolvedBlock, + setResolved, + isResolved, + setOpenedBlock, + setManualData, + updateRemediationList, + } = useScannerWizardContext(); + + const [loading, setLoading] = useState(false); + const [firstOpen, setFirstOpen] = useState(true); + + const updateData = (data) => { + const existing = manualData[openedBlock]?.[current] || {}; + const updated = [...(manualData[openedBlock] || [])]; + updated[current] = { ...existing, ...data }; + + setManualData({ + ...manualData, + [openedBlock]: updated, + }); + }; + + const sendEvent = (method) => { + mixpanelService.sendEvent(mixpanelEvents.backgroundAdaptorChanged, { + method, + }); + }; + + useEffect(() => { + if (!firstOpen && isResolved(BLOCKS.colorContrast)) { + removeExistingFocus(); + setOpenedBlock(BLOCKS.main); + } + setFirstOpen(false); + }, [manualData]); + + useEffect(() => { + if (!item?.node?.getAttribute(DATA_INITIAL_COLOR)) { + const initialColor = + manualData[openedBlock]?.[current]?.color || item.messageArgs[3]; + item.node.setAttribute(DATA_INITIAL_COLOR, initialColor); + item.node.style.setProperty('color', initialColor, 'important'); + } + }, [item]); + + const { + color = item.messageArgs[3], + background = item.messageArgs[4], + parents = [item.path.dom], + resolved = false, + backgroundChanged = false, + } = manualData[openedBlock]?.[current] || {}; + + const changeColor = (updColor) => { + item.node?.style?.setProperty('color', updColor, 'important'); + updateData({ color: updColor, resolved: false }); + }; + + const changeBackground = (updBackground) => { + const element = getElementByXPath(parents.at(-1)); + if (!element) { + return; + } + + if (!element.getAttribute(DATA_INITIAL_BG)) { + const initial = window + .getComputedStyle(element) + .getPropertyValue('background-color'); + element.setAttribute(DATA_INITIAL_BG, initial); + } + + element.style?.setProperty('background-color', updBackground, 'important'); + updateData({ + background: updBackground, + resolved: false, + backgroundChanged: true, + }); + }; + + const setParentBackground = (nextElement, element) => { + if (!nextElement) { + return; + } + + if (!nextElement.getAttribute(DATA_INITIAL_BG)) { + const initial = window + .getComputedStyle(nextElement) + .getPropertyValue('background-color'); + nextElement.setAttribute(DATA_INITIAL_BG, initial); + } + + element?.style?.setProperty( + 'background-color', + element?.getAttribute(DATA_INITIAL_BG), + 'important', + ); + + nextElement.style?.setProperty('background-color', background, 'important'); + }; + + const setParentLarger = () => { + const element = getElementByXPath(parents.at(-1)); + const parent = element?.parentElement; + if (!element || !parent) { + return; + } + + try { + const xpath = getXPath(parent, { ignoreId: true }); + focusOnElement(parent, BACKGROUND_ELEMENT_CLASS); + setParentBackground(parent, element); + + updateData({ + parents: [...parents, xpath], + resolved: false, + }); + sendEvent('plus'); + } catch (error) { + console.warn('Failed to get XPath for parent element:', error); + } + }; + + const setParentSmaller = () => { + const newParents = parents.slice(0, -1); + const nextElement = getElementByXPath(newParents.at(-1)); + if (parents.length <= 1 || !nextElement) { + return; + } + + if (newParents.length > 1) { + focusOnElement(nextElement, BACKGROUND_ELEMENT_CLASS); + } else { + removeExistingFocus(BACKGROUND_ELEMENT_CLASS); + } + + setParentBackground(nextElement); + updateData({ parents: newParents, resolved: false }); + sendEvent('minus'); + }; + + const isValidHexColor = (str) => + /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(str.trim()); + + const isValidCSS = (cssText) => { + try { + // Basic checks for common malicious patterns + if (!cssText || typeof cssText !== 'string') { + return false; + } + + // Check for basic CSS structure and disallow dangerous patterns + const dangerousPatterns = [ + /@import/i, + /javascript:/i, + /expression\s*\(/i, + /behavior\s*:/i, + /binding\s*:/i, + /-moz-binding/i, + ]; + + if (dangerousPatterns.some((pattern) => pattern.test(cssText))) { + return false; + } + + // More comprehensive CSS structure validation + const cssRegex = /^[\s\S]*\{\s*[\s\S]+:\s*[\s\S]+;\s*\}[\s\S]*$/; + const hasBasicStructure = cssRegex.test( + cssText.replace(/\s+/g, ' ').trim(), + ); + + // Additional validation: check for balanced braces + const openBraces = (cssText.match(/\{/g) || []).length; + const closeBraces = (cssText.match(/\}/g) || []).length; + + return hasBasicStructure && openBraces === closeBraces && openBraces > 0; + } catch (e) { + return false; + } + }; + + const buildCSSRule = () => { + if (!isValidHexColor(color) || !isValidHexColor(background)) { + throw new Error('Invalid hex color input detected'); + } + try { + const colorSelector = getElementCSSSelector(item.path.dom); + const bgSelector = getElementCSSSelector( + parents.length > 0 ? parents.at(-1) : item.path.dom, + ); + + const colorRule = + color !== item.messageArgs[3] + ? `${colorSelector} {color: ${color} !important;}` + : ''; + const bgRule = + background !== item.messageArgs[4] + ? `${bgSelector} {background-color: ${background} !important;}` + : ''; + + const css = `${colorRule}${bgRule}`; + + return isValidCSS(css) ? css : ''; + } catch (e) { + console.warn('Failed to convert XPath to CSS selector', e); + return ''; + } + }; + + const onSubmit = async () => { + setLoading(true); + try { + await APIScanner.submitRemediation({ + url: window?.ea11yScannerData?.pageData?.url, + remediation: { + rule: buildCSSRule(), + category: item.reasonCategory.match(/\((AAA?|AA?|A)\)/)?.[1] || '', + type: 'STYLES', + xpath: item.path.dom, + }, + rule: item.ruleId, + group: BLOCKS.colorContrast, + }); + + updateData({ resolved: true }); + + item.node?.removeAttribute(DATA_INITIAL_COLOR); + getElementByXPath( + parents.length > 0 ? parents.at(-1) : item.path.dom, + )?.removeAttribute(DATA_INITIAL_BG); + + removeExistingFocus(); + setCurrent(current + 1); + setResolved(resolvedBlock + 1); + void updateRemediationList(); + } catch (error) { + console.error('Failed to submit remediation:', error); + } finally { + setLoading(false); + } + }; + + return { + color, + background, + parents, + resolved, + backgroundChanged, + loading, + changeColor, + changeBackground, + setParentLarger, + setParentSmaller, + onSubmit, + }; +}; + +useColorContrastForm.propTypes = { + item: scannerItem.isRequired, + current: PropTypes.number.isRequired, + setCurrent: PropTypes.func.isRequired, +}; diff --git a/modules/scanner/assets/js/hooks/use-copy-to-clipboard.js b/modules/scanner/assets/js/hooks/use-copy-to-clipboard.js index 7d06402d..8c47aaf9 100644 --- a/modules/scanner/assets/js/hooks/use-copy-to-clipboard.js +++ b/modules/scanner/assets/js/hooks/use-copy-to-clipboard.js @@ -1,6 +1,5 @@ import clipboardCopy from 'clipboard-copy'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; -import { BLOCK_TITLES } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { useState } from '@wordpress/element'; @@ -14,7 +13,7 @@ export const useCopyToClipboard = () => { mixpanelService.sendEvent(mixpanelEvents.copySnippetClicked, { snippet_type: type, snippet_content: snippet, - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, source, }); }; diff --git a/modules/scanner/assets/js/hooks/use-manage-actions.js b/modules/scanner/assets/js/hooks/use-manage-actions.js index 1f4ef5a4..9961ffdf 100644 --- a/modules/scanner/assets/js/hooks/use-manage-actions.js +++ b/modules/scanner/assets/js/hooks/use-manage-actions.js @@ -1,7 +1,6 @@ import { useToastNotification } from '@ea11y-apps/global/hooks'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; -import { BLOCK_TITLES } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -20,12 +19,13 @@ export const useManageActions = (current = null) => { const [activeRequest, setActiveRequest] = useState(false); - const updateAllRemediationForPage = (active) => async () => { + const updateAllRemediationForPage = (active, group) => async () => { try { setLoading(true); await APIScanner.updateRemediationStatusForPage({ url: window?.ea11yScannerData?.pageData?.url, active, + group, }); setIsManageChanged(true); await updateRemediationList(); @@ -33,7 +33,10 @@ export const useManageActions = (current = null) => { mixpanelEvents[active ? 'remediationEnabled' : 'remediationDisabled'], { action_type: active ? 'enable_all' : 'disable_all', - remediations_amount: remediations?.length, + remediations_amount: group + ? sortedRemediation[group] + : remediations?.length, + category: group || 'all', }, ); } catch (e) { @@ -44,24 +47,32 @@ export const useManageActions = (current = null) => { } }; - const deleteAllRemediationForPage = async () => { + const deleteAllRemediationForPage = async (group) => { try { setLoading(true); await APIScanner.deleteRemediationForPage({ url: window?.ea11yScannerData?.pageData?.url, + group, }); await mixpanelService.sendEvent(mixpanelEvents.remediationRemoved, { action_type: 'remove_all', - remediations_amount: remediations?.length, + remediations_amount: group + ? sortedRemediation[group] + : remediations?.length, + category: group || 'all', }); - const url = new URL(window.location.href); - url.searchParams.delete('open-ea11y-assistant'); - url.searchParams.delete('open-ea11y-assistant-src'); - url.searchParams.append('open-ea11y-assistant', '1'); + if (group) { + await updateRemediationList(); + } else { + const url = new URL(window.location.href); + url.searchParams.delete('open-ea11y-assistant'); + url.searchParams.delete('open-ea11y-assistant-src'); + url.searchParams.append('open-ea11y-assistant', '1'); - window.location.assign(url); + window.location.assign(url); + } } catch (e) { console.error(e); error(__('An error occurred.', 'pojo-accessibility')); @@ -90,7 +101,7 @@ export const useManageActions = (current = null) => { mixpanelEvents[active ? 'remediationEnabled' : 'remediationDisabled'], { action_type: active ? 'enable_specific' : 'disable_specific', - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, issue_type: current.rule, }, ); @@ -119,7 +130,7 @@ export const useManageActions = (current = null) => { setIsManageChanged(true); mixpanelService.sendEvent(mixpanelEvents.remediationRemoved, { action_type: 'remove_specific', - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, issue_type: current.rule, }); } catch (e) { @@ -150,7 +161,7 @@ export const useManageActions = (current = null) => { mixpanelService.sendEvent(mixpanelEvents.applyFixButtonClicked, { fix_method: 'manual', snippet_content: strContent, - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, source: 'remediation', }); } catch (e) { diff --git a/modules/scanner/assets/js/hooks/use-manual-fix-form.js b/modules/scanner/assets/js/hooks/use-manual-fix-form.js index cbf0b018..19baa802 100644 --- a/modules/scanner/assets/js/hooks/use-manual-fix-form.js +++ b/modules/scanner/assets/js/hooks/use-manual-fix-form.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { useToastNotification } from '@ea11y-apps/global/hooks'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { APIScanner } from '@ea11y-apps/scanner/api/APIScanner'; -import { BLOCK_TITLES, BLOCKS } from '@ea11y-apps/scanner/constants'; +import { BLOCKS } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { scannerItem } from '@ea11y-apps/scanner/types/scanner-item'; import { removeExistingFocus } from '@ea11y-apps/scanner/utils/focus-on-element'; @@ -102,8 +102,9 @@ export const useManualFixForm = ({ item, current }) => { fix_method: manualEdit ? 'manual' : 'AI', issue_type: item.message, snippet_content: replace, - category_name: BLOCK_TITLES[openedBlock], + category_name: openedBlock, source: 'assistant', + page_url: window.ea11yScannerData?.pageData?.url, }); void updateRemediationList(); diff --git a/modules/scanner/assets/js/images/index.js b/modules/scanner/assets/js/images/index.js index 1251b717..ef88965f 100644 --- a/modules/scanner/assets/js/images/index.js +++ b/modules/scanner/assets/js/images/index.js @@ -2,3 +2,5 @@ export { Logo } from './logo'; export { ResolvedImage } from './resolved-image'; export { ErrorImage } from './error-image'; export { NotConnectedImage } from './not-connected-image'; +export { SunIcon } from './sun-icon'; +export { SunOffIcon } from './sun-off-icon'; diff --git a/modules/scanner/assets/js/images/sun-icon.js b/modules/scanner/assets/js/images/sun-icon.js new file mode 100644 index 00000000..9a8cb34f --- /dev/null +++ b/modules/scanner/assets/js/images/sun-icon.js @@ -0,0 +1,20 @@ +export const SunIcon = () => { + return ( + + + + ); +}; diff --git a/modules/scanner/assets/js/images/sun-off-icon.js b/modules/scanner/assets/js/images/sun-off-icon.js new file mode 100644 index 00000000..76a7814a --- /dev/null +++ b/modules/scanner/assets/js/images/sun-off-icon.js @@ -0,0 +1,20 @@ +export const SunOffIcon = () => { + return ( + + + + ); +}; diff --git a/modules/scanner/assets/js/layouts/alt-text-layout.js b/modules/scanner/assets/js/layouts/alt-text-layout.js index ea3d91cf..c48d6167 100644 --- a/modules/scanner/assets/js/layouts/alt-text-layout.js +++ b/modules/scanner/assets/js/layouts/alt-text-layout.js @@ -1,7 +1,7 @@ import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { AltTextForm } from '@ea11y-apps/scanner/components/alt-text-form'; -import { AltTextNavigation } from '@ea11y-apps/scanner/components/alt-text-navigation'; -import { BLOCK_TITLES, BLOCKS } from '@ea11y-apps/scanner/constants'; +import { FormNavigation } from '@ea11y-apps/scanner/components/form-navigation'; +import { BLOCKS } from '@ea11y-apps/scanner/constants'; import { useScannerWizardContext } from '@ea11y-apps/scanner/context/scanner-wizard-context'; import { StyledContent } from '@ea11y-apps/scanner/styles/app.styles'; import { @@ -28,7 +28,7 @@ export const AltTextLayout = () => { issue_type: item.message, rule_id: item.ruleId, wcag_level: item.reasonCategory.match(/\((AAA?|AA?|A)\)/)?.[1] || '', - category_name: BLOCK_TITLES[BLOCKS.altText], + category_name: BLOCKS.altText, }); }, [current]); @@ -47,7 +47,7 @@ export const AltTextLayout = () => { current={current} setCurrent={changeNavigation} /> - { + const { sortedViolations, isResolved } = useScannerWizardContext(); + const [current, setCurrent] = useState(0); + + const resolved = isResolved(BLOCKS.colorContrast); + + useEffect(() => { + const item = sortedViolations.colorContrast?.[current]; + if (!resolved && sortedViolations.colorContrast?.length) { + focusOnElement(item?.node, COLOR_ELEMENT_CLASS); + } else { + removeExistingFocus(); + } + + if (item) { + mixpanelService.sendEvent(mixpanelEvents.issueSelected, { + issue_type: item.message, + rule_id: item.ruleId, + wcag_level: item.reasonCategory.match(/\((AAA?|AA?|A)\)/)?.[1] || '', + category_name: BLOCKS.colorContrast, + current_contrast_ratio: item.messageArgs[0], + scenario: + item.messageArgs[3] && item.messageArgs[4] + ? 'regular_flow' + : 'gradient', + }); + } + }, [current]); + + const changeNavigation = (index) => { + if (index > (sortedViolations.colorContrast?.length || 0) - 1) { + setCurrent(0); + } else { + setCurrent(index); + } + }; + + return ( + + + + + ); +}; diff --git a/modules/scanner/assets/js/layouts/main-layout.js b/modules/scanner/assets/js/layouts/main-layout.js index ce75e7a9..1c1b9f72 100644 --- a/modules/scanner/assets/js/layouts/main-layout.js +++ b/modules/scanner/assets/js/layouts/main-layout.js @@ -7,9 +7,10 @@ import { __ } from '@wordpress/i18n'; export const MainLayout = () => { return ( - + {__('All issues', 'pojo-accessibility')} + ); diff --git a/modules/scanner/assets/js/layouts/manual-layout.js b/modules/scanner/assets/js/layouts/manual-layout.js index 01575ab4..f9981ed9 100644 --- a/modules/scanner/assets/js/layouts/manual-layout.js +++ b/modules/scanner/assets/js/layouts/manual-layout.js @@ -43,10 +43,12 @@ export const ManualLayout = () => { checked={manualData[openedBlock][index]?.resolved || false} aria-label={__('Resolved', 'pojo-accessibility')} /> - + + {uxMessaging[item.ruleId]?.violationName ?? item.category} + ))} diff --git a/modules/scanner/assets/js/list-column.js b/modules/scanner/assets/js/list-column.js new file mode 100644 index 00000000..935ad5de --- /dev/null +++ b/modules/scanner/assets/js/list-column.js @@ -0,0 +1,174 @@ +/** + * Accessibility List Column Enhancement + * Handles responsive button text and CSS tooltips based on available column space + */ + +class EA11yListColumn { + constructor() { + this.init(); + } + + init() { + // Wait for DOM to be ready + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => + this.setupEnhancements(), + ); + } else { + this.setupEnhancements(); + } + + // Also recheck after a short delay to handle CSS timing issues + setTimeout(() => { + this.setupEnhancements(); + }, 500); + } + + setupEnhancements() { + this.buttons = document.querySelectorAll('.ea11y-accessibility-button'); + this.columnTitles = document.querySelectorAll('.ea11y-column-title'); + + if (this.buttons.length === 0) { + return; + } + + this.setupResponsiveButtons(); + this.setupResponsiveColumnTitles(); + this.setupResizeObserver(); + this.setupWindowResize(); + } + + setupWindowResize() { + // Add window resize listener as additional fallback + let resizeTimeout; + window.addEventListener('resize', () => { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + this.setupResponsiveButtons(); + this.setupResponsiveColumnTitles(); + }, 100); + }); + } + + setupResponsiveButtons() { + this.buttons.forEach((button) => { + this.updateButton(button); + }); + } + + setupResponsiveColumnTitles() { + this.columnTitles.forEach((title) => { + this.updateColumnTitle(title); + }); + } + + updateButton(button) { + const column = button.closest('td'); + if (!column) { + return; + } + + // Use actual column width to determine behavior + const columnWidth = column.offsetWidth; + const textSpan = button.querySelector('.ea11y-button-text'); + if (!textSpan) { + return; + } + + const fullText = button.dataset.fullText; + const shortText = button.dataset.shortText; + + // Threshold for switching to compact mode (can be adjusted) + const compactThreshold = 100; + + if (columnWidth < compactThreshold) { + // Narrow column: short text, smaller min-width, show tooltip + textSpan.textContent = shortText; + button.style.minWidth = '50px'; + button.classList.remove('ea11y-tooltip-hidden'); + } else { + // Wide column: full text, larger min-width, hide tooltip + textSpan.textContent = fullText; + button.style.minWidth = '80px'; + button.classList.add('ea11y-tooltip-hidden'); + } + } + + updateColumnTitle(title) { + const column = title.closest('th'); + if (!column) { + return; + } + + const titleAnchor = title.parentElement.querySelector('a'); + if (!titleAnchor) { + return; + } + + // Use actual column width to determine behavior + const columnWidth = column.offsetWidth; + + // Threshold for hiding title and showing tooltip + const hideThreshold = 100; + + if (columnWidth < hideThreshold) { + title.style.display = 'none'; + titleAnchor.classList.remove('ea11y-tooltip-hidden'); + } else { + title.style.display = ''; + titleAnchor.classList.add('ea11y-tooltip-hidden'); + } + } + + setupResizeObserver() { + // Use ResizeObserver to detect column width changes + if (window.ResizeObserver) { + const resizeObserver = new ResizeObserver((entries) => { + entries.forEach((entry) => { + const column = entry.target; + + // Handle button updates + const button = column.querySelector('.ea11y-accessibility-button'); + if (button) { + this.updateButton(button); + } + + // Handle column title updates + const title = column.querySelector('.ea11y-column-title'); + if (title) { + this.updateColumnTitle(title); + } + }); + }); + + // Observe all columns containing our buttons + this.buttons.forEach((button) => { + const column = button.closest('td'); + if (column) { + resizeObserver.observe(column); + } + }); + + // Observe all header columns containing our titles + this.columnTitles.forEach((title) => { + const headerColumn = title.closest('th'); + if (headerColumn) { + resizeObserver.observe(headerColumn); + } + }); + } else { + // Fallback for older browsers + let resizeTimeout; + window.addEventListener('resize', () => { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + this.setupResponsiveButtons(); + this.setupResponsiveColumnTitles(); + }, 250); + }); + } + } +} + +// Initialize when script loads +new EA11yListColumn(); diff --git a/modules/scanner/assets/js/services/scanner-wizard.js b/modules/scanner/assets/js/services/scanner-wizard.js index 9d7fc9c8..5a9f5940 100644 --- a/modules/scanner/assets/js/services/scanner-wizard.js +++ b/modules/scanner/assets/js/services/scanner-wizard.js @@ -11,6 +11,7 @@ const load = async () => { const script = document.createElement('script'); script.src = scriptSrc; + script.referrerPolicy = 'strict-origin-when-cross-origin'; script.async = true; script.onload = () => { diff --git a/modules/scanner/assets/js/styles/alt-text-form.styles.js b/modules/scanner/assets/js/styles/alt-text-form.styles.js index edf68f74..b6f8963f 100644 --- a/modules/scanner/assets/js/styles/alt-text-form.styles.js +++ b/modules/scanner/assets/js/styles/alt-text-form.styles.js @@ -1,14 +1,7 @@ -import Box from '@elementor/ui/Box'; import InputLabel from '@elementor/ui/InputLabel'; import Paper from '@elementor/ui/Paper'; import { styled } from '@elementor/ui/styles'; -export const StyledBox = styled(Box)` - display: flex; - flex-direction: column; - gap: ${({ theme }) => theme.spacing(2)}; -`; - export const StyledLabel = styled(InputLabel)` display: flex; align-items: start; diff --git a/modules/scanner/assets/js/styles/app.styles.js b/modules/scanner/assets/js/styles/app.styles.js index 15cd4453..ee09445e 100644 --- a/modules/scanner/assets/js/styles/app.styles.js +++ b/modules/scanner/assets/js/styles/app.styles.js @@ -8,12 +8,17 @@ import Paper from '@elementor/ui/Paper'; import Skeleton from '@elementor/ui/Skeleton'; import Typography from '@elementor/ui/Typography'; import { styled } from '@elementor/ui/styles'; +import { ColorPickerStyles } from '@ea11y-apps/scanner/styles/react-colourful.styles'; -export const StyledPaper = styled(Paper)` +export const AppContainer = styled(Paper)` position: relative; width: 425px; min-height: 100vh; height: fit-content; + pointer-events: auto; + + // Include color picker styles to styled components for prevent problem with cache + ${ColorPickerStyles} `; export const HeaderCard = styled(Card)` @@ -113,6 +118,44 @@ export const StyledButton = styled(Button)` font-weight: 400; justify-content: start; padding: 0; + + &:focus .MuiPaper-root, + &:focus-visible .MuiPaper-root { + background-color: ${({ theme }) => theme.palette.action.hover}; + } +`; + +export const ManageButtonWrap = styled(Box)` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(1.5)}; + border: 1px solid ${({ theme }) => theme.palette.action.focus}; + border-radius: ${({ theme }) => theme.shape.borderRadius}px; + padding-right: ${({ theme }) => theme.spacing(1.5)}; + &:hover, + &:focus .MuiPaper-root, + &:focus-visible .MuiPaper-root { + background-color: ${({ theme, disabled }) => + !disabled ? theme.palette.action.hover : 'transparent'}; + } +`; + +export const ActionButton = styled(Button)` + font-weight: 400; + justify-content: start; + padding: ${({ theme }) => theme.spacing(1.5)}; + + &:hover, + &:focus, + &:focus-visible { + background-color: transparent; + } +`; + +export const ManageButtonGroup = styled(Box)` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing(0.5)}; `; export const UpgradeContentContainer = styled(Box)` @@ -137,3 +180,9 @@ export const StyledBlockButtonsBox = styled(Box)` export const DisabledMenuItemText = styled(MenuItemText)` color: ${({ theme }) => theme.palette.text.disabled}; `; + +export const StyledBox = styled(Box)` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(3)}; +`; diff --git a/modules/scanner/assets/js/styles/react-colourful.styles.js b/modules/scanner/assets/js/styles/react-colourful.styles.js new file mode 100644 index 00000000..e5b6ca42 --- /dev/null +++ b/modules/scanner/assets/js/styles/react-colourful.styles.js @@ -0,0 +1,117 @@ +import { css } from '@elementor/ui/styles'; + +export const ColorPickerStyles = css` + .react-colorful { + position: relative; + display: flex; + flex-direction: column; + width: 200px; + height: 200px; + user-select: none; + cursor: default; + } + + .react-colorful__saturation { + position: relative; + flex-grow: 1; + border-color: transparent; /* Fixes https://github.com/omgovich/react-colorful/issues/139 */ + border-bottom: 12px solid #000; + border-radius: 8px 8px 0 0; + background-image: + linear-gradient(to top, #000, rgba(0, 0, 0, 0)), + linear-gradient(to right, #fff, rgba(255, 255, 255, 0)); + } + + .react-colorful__pointer-fill, + .react-colorful__alpha-gradient { + content: ''; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + pointer-events: none; + border-radius: inherit; + } + + /* Improve elements rendering on light backgrounds */ + + .react-colorful__alpha-gradient, + .react-colorful__saturation { + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.05); + } + + .react-colorful__hue, + .react-colorful__alpha { + position: relative; + height: 24px; + } + + .react-colorful__hue { + background: linear-gradient( + to right, + #f00 0%, + #ff0 17%, + #0f0 33%, + #0ff 50%, + #00f 67%, + #f0f 83%, + #f00 100% + ); + } + + /* Round bottom corners of the last element: \`Hue\` for \`ColorPicker\` or \`Alpha\` for \`AlphaColorPicker\` */ + + .react-colorful__last-control { + border-radius: 0 0 8px 8px; + } + + .react-colorful__interactive { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + border-radius: inherit; + outline: none; + /* Don't trigger the default scrolling behavior when the event is originating from this element */ + touch-action: none; + } + + .react-colorful__pointer { + position: absolute; + z-index: 1; + box-sizing: border-box; + width: 28px; + height: 28px; + transform: translate(-50%, -50%); + background-color: #fff; + border: 2px solid #fff; + border-radius: 50%; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + } + + .react-colorful__interactive:focus .react-colorful__pointer { + transform: translate(-50%, -50%) scale(1.1); + } + + /* Chessboard-like pattern for alpha related elements */ + + .react-colorful__alpha, + .react-colorful__alpha-pointer { + background-color: #fff; + background-image: url('data:image/svg+xml,'); + } + + /* Display the saturation pointer over the hue one */ + + .react-colorful__saturation-pointer { + z-index: 3; + } + + /* Display the hue pointer over the alpha one */ + + .react-colorful__hue-pointer { + z-index: 2; + } +`; diff --git a/modules/scanner/assets/js/types/scanner-item.js b/modules/scanner/assets/js/types/scanner-item.js index 5af412df..3f178aa8 100644 --- a/modules/scanner/assets/js/types/scanner-item.js +++ b/modules/scanner/assets/js/types/scanner-item.js @@ -8,6 +8,7 @@ export const scannerItem = PropTypes.shape({ aria: PropTypes.string.isRequired, selector: PropTypes.string.isRequired, }).isRequired, + messageArgs: PropTypes.arrayOf(PropTypes.string), reasonCategory: PropTypes.string.isRequired, category: PropTypes.string.isRequired, level: PropTypes.string.isRequired, diff --git a/modules/scanner/assets/js/utils/calc-color-ratio.js b/modules/scanner/assets/js/utils/calc-color-ratio.js new file mode 100644 index 00000000..4d4bb116 --- /dev/null +++ b/modules/scanner/assets/js/utils/calc-color-ratio.js @@ -0,0 +1,41 @@ +import { hexToRGB } from '@ea11y-apps/scanner/utils/convert-colors'; + +export const getLuminance = (r, g, b) => { + const toLinear = (c) => { + const s = c / 255; + return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4); + }; + const [lr, lg, lb] = [r, g, b].map(toLinear); + return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb; +}; + +export const contrastRatio = (rgb1, rgb2) => { + const [l1, l2] = [getLuminance(...rgb1), getLuminance(...rgb2)]; + const [lighter, darker] = [Math.max(l1, l2), Math.min(l1, l2)]; + return (lighter + 0.05) / (darker + 0.05); +}; + +export const isLargeText = (el) => { + if (!el) { + return false; + } + const { fontSize, fontWeight } = window.getComputedStyle(el); + const size = parseFloat(fontSize); // px + const weight = parseInt(fontWeight, 10); + const isBold = weight >= 700; + const threshold = isBold ? 18.66 : 24; + return size >= threshold; +}; + +export const checkContrastAA = (fgHex, bgHex, el) => { + const fg = hexToRGB(fgHex); + const bg = hexToRGB(bgHex); + const ratio = contrastRatio(fg, bg); + const large = isLargeText(el); + const passesAA = ratio >= (large ? 3 : 4.5); + return { + ratio: +ratio.toFixed(2), + largeText: large, + passesAA, + }; +}; diff --git a/modules/scanner/assets/js/utils/convert-colors.js b/modules/scanner/assets/js/utils/convert-colors.js new file mode 100644 index 00000000..26e9b17a --- /dev/null +++ b/modules/scanner/assets/js/utils/convert-colors.js @@ -0,0 +1,89 @@ +export const expandHex = (hex) => { + hex = hex.replace(/^#/, ''); + if (hex.length === 3) { + hex = hex + .split('') + .map((c) => c + c) + .join(''); + } + return `#${hex}`; +}; + +export const hexToRGB = (hex) => { + hex = expandHex(hex).replace(/^#/, ''); + const num = parseInt(hex, 16); + // eslint-disable-next-line no-bitwise + return [(num >> 16) & 255, (num >> 8) & 255, num & 255]; +}; + +export const hexToHsl = (hex) => { + hex = expandHex(hex).replace(/^#/, ''); + const r = parseInt(hex.slice(0, 2), 16) / 255; + const g = parseInt(hex.slice(2, 4), 16) / 255; + const b = parseInt(hex.slice(4, 6), 16) / 255; + + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + let h = (max + min) / 2; + let s = (max + min) / 2; + const l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h *= 60; + } + + return { + h: Math.round(h), + s: Math.round(s * 100), + l: Math.round(l * 100), + }; +}; + +export const hslToHex = ({ h, s, l }) => { + s /= 100; + l /= 100; + + const c = (1 - Math.abs(2 * l - 1)) * s; + const x = c * (1 - Math.abs(((h / 60) % 2) - 1)); + const m = l - c / 2; + + let r; + let g; + let b; + + if (h < 60) { + [r, g, b] = [c, x, 0]; + } else if (h < 120) { + [r, g, b] = [x, c, 0]; + } else if (h < 180) { + [r, g, b] = [0, c, x]; + } else if (h < 240) { + [r, g, b] = [0, x, c]; + } else if (h < 300) { + [r, g, b] = [x, 0, c]; + } else { + [r, g, b] = [c, 0, x]; + } + + const toHex = (v) => { + const hex = Math.round((v + m) * 255).toString(16); + return hex.length === 1 ? '0' + hex : hex; + }; + + return `#${toHex(r)}${toHex(g)}${toHex(b)}`; +}; diff --git a/modules/scanner/assets/js/utils/focus-on-element.js b/modules/scanner/assets/js/utils/focus-on-element.js index 62e65ae7..0305f8bd 100644 --- a/modules/scanner/assets/js/utils/focus-on-element.js +++ b/modules/scanner/assets/js/utils/focus-on-element.js @@ -1,15 +1,48 @@ -import { CURRENT_ELEMENT_CLASS } from '@ea11y-apps/scanner/constants'; +import { + BACKGROUND_ELEMENT_CLASS, + COLOR_ELEMENT_CLASS, + CURRENT_ELEMENT_CLASS, + DATA_INITIAL_BG, + DATA_INITIAL_COLOR, +} from '@ea11y-apps/scanner/constants'; -export const focusOnElement = (element) => { - removeExistingFocus(); +export const focusOnElement = (element, queryClass = null) => { + removeExistingFocus(queryClass); if (element) { - element.classList.add(CURRENT_ELEMENT_CLASS); - element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + element.classList.add(queryClass ?? CURRENT_ELEMENT_CLASS); + if (queryClass !== BACKGROUND_ELEMENT_CLASS) { + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } } }; -export const removeExistingFocus = () => { - document.querySelectorAll(`.${CURRENT_ELEMENT_CLASS}`).forEach((element) => { - element.classList.remove(CURRENT_ELEMENT_CLASS); - }); +export const resetStyles = (element) => { + const bg = element.getAttribute(DATA_INITIAL_BG); + const color = element.getAttribute(DATA_INITIAL_COLOR); + + if (bg && element?.style) { + element.style['background-color'] = bg; + element.removeAttribute(DATA_INITIAL_BG); + } + if (color && element?.style) { + element.style.color = color; + element.removeAttribute(DATA_INITIAL_COLOR); + } +}; + +export const removeExistingFocus = (queryClass = null) => { + document + .querySelectorAll( + queryClass + ? `.${queryClass}` + : `.${CURRENT_ELEMENT_CLASS}, .${COLOR_ELEMENT_CLASS}, .${BACKGROUND_ELEMENT_CLASS}`, + ) + .forEach((element) => { + element.classList.remove( + CURRENT_ELEMENT_CLASS, + COLOR_ELEMENT_CLASS, + BACKGROUND_ELEMENT_CLASS, + ); + resetStyles(element); + }); }; diff --git a/modules/scanner/assets/js/utils/get-element-css-selector.js b/modules/scanner/assets/js/utils/get-element-css-selector.js new file mode 100644 index 00000000..e2fd0457 --- /dev/null +++ b/modules/scanner/assets/js/utils/get-element-css-selector.js @@ -0,0 +1,65 @@ +import { + BACKGROUND_ELEMENT_CLASS, + COLOR_ELEMENT_CLASS, + CURRENT_ELEMENT_CLASS, +} from '@ea11y-apps/scanner/constants'; +import { getElementByXPath } from '@ea11y-apps/scanner/utils/get-element-by-xpath'; + +export const getElementCSSSelector = (xpath) => { + let element = getElementByXPath(xpath); + if (!element || !(element instanceof Element)) { + return null; + } + + const ignoredClasses = new Set([ + CURRENT_ELEMENT_CLASS, + COLOR_ELEMENT_CLASS, + BACKGROUND_ELEMENT_CLASS, + ]); + + const parts = []; + + while (element && element.nodeType === Node.ELEMENT_NODE) { + let selector = element.tagName.toLowerCase(); + + if (element.id) { + selector += `#${element.id}`; + parts.unshift(selector); + break; // Stop at ID + } + + // Add classes unless it's or ignored + if (element.className && element.tagName.toLowerCase() !== 'body') { + const classList = element.className + .trim() + .split(/\s+/) + .filter((cls) => cls && !ignoredClasses.has(cls)); + if (classList.length) { + selector += '.' + classList.join('.'); + } + } + + // Add :nth-of-type if needed + const parent = element.parentNode; + if ( + parent && + !( + parent.tagName?.toLowerCase() === 'body' && + element.tagName?.toLowerCase() === 'div' + ) + ) { + const siblings = Array.from(parent.children).filter( + (sibling) => sibling.tagName === element.tagName, + ); + if (siblings.length > 1) { + const index = siblings.indexOf(element) + 1; + selector += `:nth-of-type(${index})`; + } + } + + parts.unshift(selector); + element = element.parentElement; + } + + return parts.join(' > '); +}; diff --git a/modules/scanner/components/list-column.php b/modules/scanner/components/list-column.php index 77973ee1..ad3b4240 100644 --- a/modules/scanner/components/list-column.php +++ b/modules/scanner/components/list-column.php @@ -3,8 +3,10 @@ namespace EA11y\Modules\Scanner\Components; use EA11y\Classes\Database\Exceptions\Missing_Table_Exception; +use EA11y\Modules\Remediation\Classes\Utils; use EA11y\Modules\Remediation\Database\Page_Entry; use EA11y\Modules\Remediation\Database\Page_Table; +use EA11y\Modules\Scanner\Database\Scan_Entry; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. @@ -29,13 +31,16 @@ public function build_column() { } public function add_accessibility_column( $columns ) { - $columns['accessibility_status'] = '' . esc_html__( 'Accessibility scans', 'pojo-accessibility' ); + $columns['accessibility_status'] = '' . esc_html__( 'Ally', 'pojo-accessibility' ) . ''; return $columns; } public function render_accessibility_column_post( $column, $post_id ) { if ( 'accessibility_status' === $column ) { - $url = get_permalink( $post_id ); + $post = get_post( $post_id ); + $url = in_array( $post->post_status, [ 'draft', 'pending', 'auto-draft' ], true ) + ? Utils::build_draft_url( $post ) + : get_permalink( $post_id ); $this->render_column_accessibility( $url ); } } @@ -63,86 +68,96 @@ private function render_column_accessibility( string $url ) { $url_trimmed = rtrim( $url, '/' ); $page = $this->get_current_page( $url_trimmed ); $has_scan_data = $page->exists(); - $violation = $page->__get( Page_Table::VIOLATIONS ); - $resolved = $page->__get( Page_Table::RESOLVED ); - - $passed = $has_scan_data && $resolved === $violation; + $latest_scan = Scan_Entry::get_scan_result( $url_trimmed, true ); + + if ( empty( $latest_scan ) ) { + $latest_scan = [ + 'counts' => [ + 'violation' => 0, + 'issuesResolved' => 0, + ], + ]; + } - $percentage = $violation > 0 - ? round( ( $resolved / $violation ) * 100 ) - : '0'; + $violation = $latest_scan['counts']['violation']; + $resolved = $latest_scan['counts']['issuesResolved']; - $level_class = $this->get_scan_level( $percentage ); + $passed = $has_scan_data && $resolved === $violation; $separator = strpos( $url, '?' ) !== false ? '&' : '?'; $assistant_url = esc_url( $url . $separator . 'open-ea11y-assistant=1&open-ea11y-assistant-src=WP' ); - /** - * Show the percentage of fixed violations or a checkmark if all violations are fixed. - */ - $chip = $passed - ? '' - : '' . esc_html( $percentage ) . '%'; - - $no_scan_icon = ''; - - /** - * Show the number of fixed and total violations or "Not scanned yet" if the page has not been scanned yet. - */ - $status_text = $has_scan_data ? esc_html( sprintf( __( '%1$s/%2$s fixed', 'pojo-accessibility' ), $resolved, $violation ) ) : esc_html__( 'Not scanned yet', 'pojo-accessibility' ); - - $status_icon = $has_scan_data ? $chip : $no_scan_icon; - - $stats = - '
-
- ' . $status_text . ' - ' . $status_icon . ' -
-
-
-
-
'; - - $button_text = $has_scan_data ? esc_html__( 'Review fixes', 'pojo-accessibility' ) : esc_html__( 'Scan now', 'pojo-accessibility' ); - $button_text = $passed ? esc_html__( 'New scan', 'pojo-accessibility' ) : $button_text; - $button_class = $has_scan_data && ! $passed ? 'button' : 'button button-primary'; - $button_icon = $passed - ? '' - : ''; - - $scan_button = sprintf( - '%3$s%4$s', - $assistant_url, - $button_class, - $button_text, - $button_icon - ); + if ( $passed ) { + $content = '' . esc_attr__( 'All accessibility issues resolved', 'pojo-accessibility' ) . ''; + } else { + if ( $has_scan_data ) { + $issues_left = $violation - $resolved; + $button_text = sprintf( + /* translators: %d: number of issues to fix */ + _n( 'Fix %d issue', 'Fix %d issues', $issues_left, 'pojo-accessibility' ), + $issues_left + ); + $tooltip_text = sprintf( + /* translators: %d: number of issues to fix */ + _n( 'Fix %d issue', 'Fix %d issues', $issues_left, 'pojo-accessibility' ), + $issues_left + ); + $button_class = 'button ea11y-accessibility-button'; + $button_style = 'color: #B91C1C; border-color: #B91C1C;'; + $short_text = esc_html__( 'Fix', 'pojo-accessibility' ); + } else { + $button_text = esc_html__( 'Scan URL', 'pojo-accessibility' ); + $tooltip_text = esc_html__( 'Scan URL', 'pojo-accessibility' ); + $button_class = 'button button-primary ea11y-accessibility-button'; + $button_style = ''; + $short_text = esc_html__( 'Scan', 'pojo-accessibility' ); + } + + $content = sprintf( + '%7$s', + $assistant_url, + $button_class, + $button_style, + esc_attr( $button_text ), + esc_attr( $short_text ), + esc_attr( $tooltip_text ), + $button_text + ); + } echo '
- ' . $stats . ' -
' . $scan_button . '
+
' . $content . '
'; } - private function get_scan_level( int $percent ): ?string { - switch ( true ) { - case ( $percent >= 0 && $percent <= 25 ): - return 'red'; - case ( $percent >= 26 && $percent <= 60 ): - return 'orange'; - case ( $percent >= 61 ): - return 'grey'; - default: - return null; - } - } - - /** * Component constructor. */ public function __construct() { add_action( 'init', [ $this, 'build_column' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + } + + /** + * Enqueue assets for the accessibility column enhancements. + */ + public function enqueue_assets() { + $screen = get_current_screen(); + + // Only load on edit.php pages (post list tables) and edit-tags.php (taxonomy list tables) + if ( ! $screen || ! in_array( $screen->base, [ 'edit', 'edit-tags' ], true ) ) { + return; + } + + // Enqueue JavaScript + wp_enqueue_script( + 'ea11y-list-column', + EA11Y_URL . 'modules/scanner/assets/js/list-column.js', + [], + EA11Y_VERSION, + true + ); + + // CSS is now included in the main ea11y-scanner-admin.scss file } } diff --git a/modules/scanner/database/scan-entry.php b/modules/scanner/database/scan-entry.php index 09ae2d13..d654d67a 100644 --- a/modules/scanner/database/scan-entry.php +++ b/modules/scanner/database/scan-entry.php @@ -38,69 +38,69 @@ public static function get_scan_result( string $url, bool $latest = false ) : ar return isset( $entries[0] ) ? json_decode( $entries[0]->summary, true ) : []; } - /** - * get_scans - * @param string $url - * @param bool $latest - * - * @return array - */ - public static function get_scans( string $url, int $limit = 10 ) : array { - $where = [ - [ - 'column' => Scans_Table::URL, - 'value' => $url, - 'operator' => '=', - ], - ]; - - $entries = Scans_Table::select( '*', $where, $limit, null, '', ['created_at' => 'desc'] ); - - return array_map( function ( $entry ) { - $entry->summary = json_decode( $entry->summary, true ); - - return $entry; - }, $entries); - } - - public static function get_by_id( int $id ) { - $where = [ - [ - 'column' => Scans_Table::ID, - 'value' => $id, - 'operator' => '=', - ], - ]; - - $entries = Scans_Table::select( '*', $where, 1 ); - - if (isset($entries[0])) { - $entries[0]->summary = json_decode( $entries[0]->summary, true ); - - return $entries[0]; - } - - return null; - } - - /** - * @param string $by - * @param string $by_value - * @param string $content - * - * @return void - */ - public static function update_scan_summary( string $by, string $by_value, string $content ): void { - $where = [ - $by => $by_value, - ]; - - $data = [ - Scans_Table::SUMMARY => $content, - ]; - - Scans_Table::update( $data, $where ); - } + /** + * get_scans + * @param string $url + * @param bool $latest + * + * @return array + */ + public static function get_scans( string $url, int $limit = 10 ) : array { + $where = [ + [ + 'column' => Scans_Table::URL, + 'value' => $url, + 'operator' => '=', + ], + ]; + + $entries = Scans_Table::select( '*', $where, $limit, null, '', [ 'created_at' => 'desc' ] ); + + return array_map( function ( $entry ) { + $entry->summary = json_decode( $entry->summary, true ); + + return $entry; + }, $entries); + } + + public static function get_by_id( int $id ) { + $where = [ + [ + 'column' => Scans_Table::ID, + 'value' => $id, + 'operator' => '=', + ], + ]; + + $entries = Scans_Table::select( '*', $where, 1 ); + + if ( isset( $entries[0] ) ) { + $entries[0]->summary = json_decode( $entries[0]->summary, true ); + + return $entries[0]; + } + + return null; + } + + /** + * @param string $by + * @param string $by_value + * @param string $content + * + * @return void + */ + public static function update_scan_summary( string $by, string $by_value, string $content ): void { + $where = [ + $by => $by_value, + ]; + + $data = [ + Scans_Table::SUMMARY => $content, + ]; + + Scans_Table::update( $data, $where ); + } /** * Create diff --git a/modules/scanner/module.php b/modules/scanner/module.php index 1718fcde..1f07d485 100644 --- a/modules/scanner/module.php +++ b/modules/scanner/module.php @@ -88,6 +88,7 @@ public function enqueue_assets() : void { 'ea11yScannerData', [ 'wpRestNonce' => wp_create_nonce( 'wp_rest' ), + 'dashboardUrl' => admin_url( 'admin.php?page=accessibility-settings' ), 'scannerUrl' => self::get_scanner_wizard_url(), 'initialScanResult' => Scan_Entry::get_scan_result( $url ), 'pageData' => [ @@ -102,6 +103,7 @@ public function enqueue_assets() : void { 'planData' => Settings::get( Settings::PLAN_DATA ), 'planScope' => Settings::get( Settings::PLAN_SCOPE ), 'pluginEnv' => Settings_Module::get_plugin_env(), + 'pluginVersion' => EA11Y_VERSION, 'isConnected' => Connect::is_connected(), 'isRTL' => is_rtl(), ] @@ -117,6 +119,21 @@ public function enqueue_admin_styles() : void { ); } + public static function is_active(): bool { + return ( + self::has_required_permissions() && + self::is_connected_and_enabled() + ); + } + + private static function has_required_permissions(): bool { + return is_user_logged_in() && current_user_can( 'manage_options' ); + } + + private static function is_connected_and_enabled(): bool { + return Connect::is_connected() && ! \EA11y\Modules\Legacy\Module::is_active(); + } + public function __construct() { Scans_Table::install(); diff --git a/modules/scanner/rest/scanner-stats.php b/modules/scanner/rest/scanner-stats.php index 11797f14..fdb04bcd 100644 --- a/modules/scanner/rest/scanner-stats.php +++ b/modules/scanner/rest/scanner-stats.php @@ -48,6 +48,16 @@ public function GET( $request ) { 'aa' => 0, 'aaa' => 0, ], + 'issue_by_category' => [ + 'altText' => 0, + 'dynamicContent' => 0, + 'formsInputsError' => 0, + 'keyboardAssistiveTech' => 0, + 'pageStructureNav' => 0, + 'tables' => 0, + 'colorContrast' => 0, + 'other' => 0, + ], ]; $pages_scanned = Page_Entry::get_pages(); @@ -62,13 +72,21 @@ public function GET( $request ) { if ( count( $recent_scans ) > 0 ) { $output['scans'] ++; - $output['issues_total'] += $recent_scans[0]->summary['counts']['violation']; - $output['issues_fixed'] += $recent_scans[0]->summary['counts']['issuesResolved']; + $output['issues_total'] += $recent_scans[0]->summary['counts']['violation'] ?? 0; + $output['issues_fixed'] += $recent_scans[0]->summary['counts']['issuesResolved'] ?? 0; } } foreach ( $remediations as $remediation ) { $output['issue_levels'][ strtolower( $remediation->category ) ] ++; + + // Map group to the correct key format expected by frontend + $group = $remediation->group; + if ( isset( $output['issue_by_category'][ $group ] ) ) { + $output['issue_by_category'][ $group ] ++; + } else { + $output['issue_by_category']['other'] ++; + } } return $this->respond_success_json( $output ); diff --git a/modules/settings/assets/js/app.js b/modules/settings/assets/js/app.js index cc8ba660..6104350e 100644 --- a/modules/settings/assets/js/app.js +++ b/modules/settings/assets/js/app.js @@ -15,7 +15,7 @@ import { useSavedSettings, useSettings, } from '@ea11y/hooks'; -import { QuotaNotices, Sidebar, TopBar } from '@ea11y/layouts'; +import { Sidebar, TopBar } from '@ea11y/layouts'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { useEffect } from '@wordpress/element'; import { usePluginSettingsContext } from './contexts/plugin-settings'; @@ -59,7 +59,6 @@ const App = () => { - { - const { isAnalyticsEnabled, updateIsAnalyticsEnabled } = - useAnalyticsContext(); - const [showConfirm, setShowConfirm] = useState(false); + const { + isAnalyticsEnabled, + handleAnalyticsToggle, + updateIsAnalyticsEnabled, + showConfirmPopup, + setShowConfirmPopup, + } = useAnalyticsContext(); - const handleToggle = () => { - if (isAnalyticsEnabled) { - updateIsAnalyticsEnabled(); - } else { - setShowConfirm(true); - } - - mixpanelService.sendEvent(mixpanelEvents.toggleClicked, { - state: isAnalyticsEnabled ? 'off' : 'on', - type: 'Enable analytics', - }); + const handleToggleClick = () => { + handleAnalyticsToggle(); }; const handleClose = () => { - setShowConfirm(false); + setShowConfirmPopup(false); mixpanelService.sendEvent(mixpanelEvents.popupButtonClicked, { data: { @@ -45,7 +41,7 @@ export const AnalyticsToggle = () => { const handleConfirm = () => { updateIsAnalyticsEnabled(); - setShowConfirm(false); + setShowConfirmPopup(false); mixpanelService.sendEvent(mixpanelEvents.popupButtonClicked, { data: { @@ -62,7 +58,7 @@ export const AnalyticsToggle = () => { } @@ -90,21 +86,28 @@ export const AnalyticsToggle = () => { sx={{ ml: 0 }} /> - - - {__('Confirm widget data tracking', 'pojo-accessibility')} - - + + + {__('Enable widget tracking?', 'pojo-accessibility')} + + + + + {__( + 'This allows Ally to record how visitors open and use your accessibility widget, unlocking real‑time analytics.', + 'pojo-accessibility', + )} + + {__( - 'Enabling data tracking let’s you see how users interact with your widget and features. Keep in mind: Real-time data processing may slightly impact a site’s performance, especially on high-traffic websites.', + 'This may slightly affect performance on high‑traffic sites.', 'pojo-accessibility', )} diff --git a/modules/settings/assets/js/components/analytics/charts-list.js b/modules/settings/assets/js/components/analytics/charts-list.js index ea853ecc..6ae1aa8f 100644 --- a/modules/settings/assets/js/components/analytics/charts-list.js +++ b/modules/settings/assets/js/components/analytics/charts-list.js @@ -2,6 +2,7 @@ import { ChevronDownIcon, InfoCircleFilledIcon } from '@elementor/icons'; import Alert from '@elementor/ui/Alert'; import AlertTitle from '@elementor/ui/AlertTitle'; import Box from '@elementor/ui/Box'; +import Button from '@elementor/ui/Button'; import Grid from '@elementor/ui/Grid'; import MenuItem from '@elementor/ui/MenuItem'; import Select from '@elementor/ui/Select'; @@ -31,6 +32,7 @@ export const ChartsList = () => { loading, period, setPeriod, + handleAnalyticsToggle, } = useAnalyticsContext(); /** @@ -58,6 +60,19 @@ export const ChartsList = () => { color="info" icon={} sx={{ width: '100%' }} + action={ + !availableDate && + !isAnalyticsEnabled && ( + + ) + } > {availableDate && !isAnalyticsEnabled && ( <> @@ -69,7 +84,7 @@ export const ChartsList = () => { )} {__( - 'We are showing you data collecting in the past', + 'We are showing you data collected in the past', 'pojo-accessibility', )} @@ -77,10 +92,10 @@ export const ChartsList = () => { {!availableDate && isAnalyticsEnabled && ( <> - {__('Not enough data', 'pojo-accessibility')} + {__('Not enough data to show yet', 'pojo-accessibility')} {__( - "We don't have enough data to show you for those days", + 'Analytics appear once enough visitors interact with your accessibility widget.', 'pojo-accessibility', )} @@ -88,10 +103,10 @@ export const ChartsList = () => { {!availableDate && !isAnalyticsEnabled && ( <> - {__('Need to switch on', 'pojo-accessibility')} + {__('Analytics are off.', 'pojo-accessibility')} {__( - "We don't have enough data to show you for those days", + 'Switch on ״Track widget data״ to start collecting usage data for your widget.', 'pojo-accessibility', )} diff --git a/modules/settings/assets/js/components/quota-bar/quota-bar-group.js b/modules/settings/assets/js/components/quota-bar/quota-bar-group.js index 2b74ede6..fefb9c3b 100644 --- a/modules/settings/assets/js/components/quota-bar/quota-bar-group.js +++ b/modules/settings/assets/js/components/quota-bar/quota-bar-group.js @@ -48,7 +48,6 @@ const QuotaBarGroup = ({ collapsible = true, popup = false }) => { const QuotaBars = () => ( - diff --git a/modules/settings/assets/js/components/quota-bar/quota-indicator.js b/modules/settings/assets/js/components/quota-bar/quota-indicator.js index a5e4fed0..1918c46f 100644 --- a/modules/settings/assets/js/components/quota-bar/quota-indicator.js +++ b/modules/settings/assets/js/components/quota-bar/quota-indicator.js @@ -9,27 +9,24 @@ import { __ } from '@wordpress/i18n'; const QuotaIndicator = () => { const { planData, openSidebar } = useSettings(); - if (!planData?.scannedPages || !planData?.visits || !planData?.aiCredits) { + if (!planData?.scannedPages || !planData?.aiCredits) { return null; // Return null if data is not available } - const { scannedPages, visits, aiCredits } = planData; + const { scannedPages, aiCredits } = planData; // calculate usage data of each quota const scannedPagesUsage = Math.round( (scannedPages.used / scannedPages.allowed) * 100, ); - const visitsUsage = Math.round((visits.used / visits.allowed) * 100); const aiCreditsUsage = Math.round((aiCredits.used / aiCredits.allowed) * 100); // check if any of the quota is 100% used - const isQuotaExceeded = - scannedPagesUsage >= 100 || visitsUsage >= 100 || aiCreditsUsage >= 100; + const isQuotaExceeded = scannedPagesUsage >= 100 || aiCreditsUsage >= 100; // check if any of the quota is 80% but not 100% used const isQuotaWarning = (scannedPagesUsage >= 80 && scannedPagesUsage < 100) || - (visitsUsage >= 80 && visitsUsage < 100) || (aiCreditsUsage >= 80 && aiCreditsUsage < 100); if (isQuotaExceeded) { diff --git a/modules/settings/assets/js/components/sidebar-menu/menu-item.js b/modules/settings/assets/js/components/sidebar-menu/menu-item.js index 726f2d2d..aa5705e9 100644 --- a/modules/settings/assets/js/components/sidebar-menu/menu-item.js +++ b/modules/settings/assets/js/components/sidebar-menu/menu-item.js @@ -97,7 +97,7 @@ const MenuItem = ({ keyName, item }) => { { /* Show infotip */ - openSidebar && item?.infotip + openSidebar && !showProIcon(item) && item?.infotip } {item?.children && ( diff --git a/modules/settings/assets/js/components/sidebar-menu/menu.js b/modules/settings/assets/js/components/sidebar-menu/menu.js index 11ff28ca..528bd422 100644 --- a/modules/settings/assets/js/components/sidebar-menu/menu.js +++ b/modules/settings/assets/js/components/sidebar-menu/menu.js @@ -10,10 +10,11 @@ import { import { __ } from '@wordpress/i18n'; import { AccessibilityAssistantContextProvider } from '../../contexts/accessibility-assistant-context'; import AccessibilityStatementTooltip from './tooltips/accessibility-statement'; +import AnalyticsTooltip from './tooltips/analytics'; export const MenuItems = { scanner: { - name: __('Accessibility scans', 'pojo-accessibility'), + name: __('Accessibility Assistant', 'pojo-accessibility'), key: 'scanner', type: 'heading', }, @@ -94,5 +95,6 @@ export const MenuItems = { sx={{ color: 'common.black' }} /> ), + infotip: , }, }; diff --git a/modules/settings/assets/js/components/sidebar-menu/tooltips/analytics.js b/modules/settings/assets/js/components/sidebar-menu/tooltips/analytics.js new file mode 100644 index 00000000..9a015be8 --- /dev/null +++ b/modules/settings/assets/js/components/sidebar-menu/tooltips/analytics.js @@ -0,0 +1,89 @@ +import { InfoCircleIcon } from '@elementor/icons'; +import Button from '@elementor/ui/Button'; +import Card from '@elementor/ui/Card'; +import CardActions from '@elementor/ui/CardActions'; +import CardContent from '@elementor/ui/CardContent'; +import CardHeader from '@elementor/ui/CardHeader'; +import Infotip from '@elementor/ui/Infotip'; +import Typography from '@elementor/ui/Typography'; +import { useSettings } from '@ea11y/hooks'; +import { useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { useAnalyticsContext } from '../../../contexts/analytics-context'; + +const AnalyticsTooltip = () => { + const { setSelectedMenu } = useSettings(); + const { handleAnalyticsToggle, isAnalyticsEnabled } = useAnalyticsContext(); + const [isOpen, setIsOpen] = useState(false); + + // Don't show tooltip if analytics is already enabled + if (isAnalyticsEnabled) { + return null; + } + + const handleOpen = () => { + setIsOpen(true); + }; + + const handleClose = () => { + setIsOpen(false); + }; + + const handleEnableTracking = () => { + // Execute the analytics functionality + setSelectedMenu('analytics'); + handleAnalyticsToggle(); + // Close the tooltip + handleClose(); + }; + + const TooltipCard = ( + + + + + + {__( + 'Get valuable insights into how visitors interact with your accessibility widget.', + 'pojo-accessibility', + )} + + + + + + + + ); + + return ( + + + + ); +}; + +export default AnalyticsTooltip; diff --git a/modules/settings/assets/js/contexts/analytics-context.js b/modules/settings/assets/js/contexts/analytics-context.js index 45b2a9cd..a8f7a1e2 100644 --- a/modules/settings/assets/js/contexts/analytics-context.js +++ b/modules/settings/assets/js/contexts/analytics-context.js @@ -1,4 +1,5 @@ import { useStorage } from '@ea11y/hooks'; +import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; import { createContext, useContext, @@ -20,6 +21,8 @@ export const AnalyticsContextProvider = ({ children }) => { elements: [], }); + const [showConfirmPopup, setShowConfirmPopup] = useState(false); + /** * Get initial logs list */ @@ -41,6 +44,19 @@ export const AnalyticsContextProvider = ({ children }) => { setPeriod(30); }; + const handleAnalyticsToggle = () => { + if (isAnalyticsEnabled) { + updateIsAnalyticsEnabled(); + } else { + setShowConfirmPopup(true); + } + + mixpanelService.sendEvent(mixpanelEvents.toggleClicked, { + state: isAnalyticsEnabled ? 'off' : 'on', + type: 'Enable analytics', + }); + }; + return ( { isProVersion, setIsProVersion, updateIsAnalyticsEnabled, + handleAnalyticsToggle, period, setPeriod, stats, loading, + showConfirmPopup, + setShowConfirmPopup, }} > {children} diff --git a/modules/settings/assets/js/pages/accessibility-statement.js b/modules/settings/assets/js/pages/accessibility-statement.js index 76a81cf2..6e411c52 100644 --- a/modules/settings/assets/js/pages/accessibility-statement.js +++ b/modules/settings/assets/js/pages/accessibility-statement.js @@ -15,10 +15,10 @@ import { } from '@ea11y/icons'; import { StatementLink } from '@ea11y/layouts'; import { - StyledBox, - StyledStatementContainer, StyledStatementPaper, StyledTitle, + StyledWideBox, + StyledBox, } from '@ea11y/pages/pages.styles'; import { GOLINKS } from '@ea11y-apps/global/constants'; import { mixpanelEvents, mixpanelService } from '@ea11y-apps/global/services'; @@ -74,13 +74,8 @@ const AccessibilityStatement = () => { return ( <> - - + + {__('Accessibility statement', 'pojo-accessibility')} @@ -226,7 +221,7 @@ const AccessibilityStatement = () => { )} - + {!accessibilityStatementData?.pageId && !showStatementLink && ( theme.spacing(4.5)}; + padding-top: ${({ theme }) => theme.spacing(4)}; + padding-bottom: ${({ theme }) => theme.spacing(4)}; + padding-left: ${({ theme }) => theme.spacing(4)}; + padding-right: ${({ theme }) => theme.spacing(4)}; + + @media (min-width: ${({ theme }) => theme.breakpoints.values.xl}px) { + padding-left: 0; + padding-right: 0; + } `; export const StyledContainer = styled(Container)` - padding: ${({ theme }) => theme.spacing(4)}; + padding-top: ${({ theme }) => theme.spacing(4)}; + padding-bottom: ${({ theme }) => theme.spacing(4)}; + padding-left: ${({ theme }) => theme.spacing(4)}; + padding-right: ${({ theme }) => theme.spacing(4)}; + + @media (min-width: ${({ theme }) => theme.breakpoints.values.xl}px) { + padding-left: 0; + padding-right: 0; + } `; export default AccessibilityAssistant; diff --git a/modules/settings/assets/js/pages/assistant/results/dropdown-menu.js b/modules/settings/assets/js/pages/assistant/results/dropdown-menu.js index 5cc3cc91..05855b66 100644 --- a/modules/settings/assets/js/pages/assistant/results/dropdown-menu.js +++ b/modules/settings/assets/js/pages/assistant/results/dropdown-menu.js @@ -38,7 +38,7 @@ export const DropdownMenu = ({ pageUrl, remediationCount }) => { }); }; - const onRunNewScan = () => { + const onRescan = () => { sendOnClickEvent('scan'); }; @@ -60,12 +60,15 @@ export const DropdownMenu = ({ pageUrl, remediationCount }) => { > + { href={ctaScan} target="_blank" rel="noreferrer" - onClick={onRunNewScan} + onClick={onRescan} + dense > - {__('New Scan', 'pojo-accessibility')} + + {__('Rescan', 'pojo-accessibility')} + {remediationCount < 1 ? ( { ], }} > - + - {__('Manage AI fixes', 'pojo-accessibility')} + {__('Manage fixes', 'pojo-accessibility')} @@ -124,12 +130,13 @@ export const DropdownMenu = ({ pageUrl, remediationCount }) => { target="_blank" rel="noreferrer" onClick={goToManagement} + dense > - {__('Manage AI fixes', 'pojo-accessibility')} + {__('Manage fixes', 'pojo-accessibility')} )} diff --git a/modules/settings/assets/js/pages/assistant/stats/category-pie-chart.js b/modules/settings/assets/js/pages/assistant/stats/category-pie-chart.js new file mode 100644 index 00000000..58ef2dfa --- /dev/null +++ b/modules/settings/assets/js/pages/assistant/stats/category-pie-chart.js @@ -0,0 +1,160 @@ +import { + ColorBlue100, + ColorBlue200, + ColorBlue300, + ColorBlue400, + ColorBlue500, + ColorBlue700, + ColorBlue900, +} from '@elementor/design-tokens/primitives'; +import Box from '@elementor/ui/Box'; +import { styled } from '@elementor/ui/styles'; +import PropTypes from 'prop-types'; +import { BLOCK_TITLES } from '@ea11y-apps/scanner/constants'; +import { __ } from '@wordpress/i18n'; + +const CategoryPieChart = ({ issueByCategory, loading }) => { + // Loading state + if (loading) { + const loadingBackground = ` + radial-gradient(closest-side, white 84%, transparent 85% 100%), + conic-gradient(#e5e7eb 0%, #f3f3f4 50%, #e5e7eb 100%) + `; + return ; + } + + // Process categories similar to issue-by-category.js + const processedCategories = () => { + // Convert to array and sort by count (descending) + const sortedCategories = Object.entries(issueByCategory || {}) + .map(([key, count]) => ({ + key, + title: BLOCK_TITLES[key] || key, + count: count || 0, + })) + .sort((a, b) => b.count - a.count); + + // Calculate total issues across all categories + const totalIssues = sortedCategories.reduce( + (sum, category) => sum + category.count, + 0, + ); + + // Take top 6 categories + const top6 = sortedCategories.slice(0, 6); + // Calculate "other" count from remaining categories + const otherCount = sortedCategories + .slice(6) + .reduce((sum, category) => sum + category.count, 0); + + // Add "other" category if there are remaining categories or if it has count + const result = [...top6]; + if (otherCount > 0 || sortedCategories.length > 6) { + result.push({ + key: 'other', + title: __('Other', 'pojo-accessibility'), + count: otherCount, + }); + } + + // Convert counts to percentages and add colors + return result.map((category, index) => ({ + key: category.key, + percentage: + totalIssues > 0 ? Math.round((category.count / totalIssues) * 100) : 0, + color: + [ + ColorBlue900, + ColorBlue700, + ColorBlue500, + ColorBlue400, + ColorBlue300, + ColorBlue200, + ColorBlue100, // for "other" + ][index] || ColorBlue100, + })); + }; + + const categories = processedCategories(); + + // Create conic-gradient string + const createConicGradient = () => { + if (categories.length === 0) { + return 'conic-gradient(#f3f3f4 0%, #f3f3f4 100%)'; + } + + let cumulativePercentage = 0; + const gradientStops = []; + + categories.forEach((category) => { + const startPercentage = cumulativePercentage; + const endPercentage = cumulativePercentage + category.percentage; + + gradientStops.push( + `${category.color} ${startPercentage}% ${endPercentage}%`, + ); + cumulativePercentage += category.percentage; + }); + + // Fill remaining space with light gray if total is less than 100% + if (cumulativePercentage < 100) { + gradientStops.push(`#f3f3f4 ${cumulativePercentage}% 100%`); + } + + return `conic-gradient(${gradientStops.join(', ')})`; + }; + + const background = ` + radial-gradient(closest-side, white 84%, transparent 85% 100%), + ${createConicGradient()} + `; + + return ; +}; + +CategoryPieChart.propTypes = { + issueByCategory: PropTypes.shape({ + altText: PropTypes.number, + dynamicContent: PropTypes.number, + formsInputsError: PropTypes.number, + keyboardAssistiveTech: PropTypes.number, + pageStructureNav: PropTypes.number, + tables: PropTypes.number, + colorContrast: PropTypes.number, + other: PropTypes.number, + }), + loading: PropTypes.bool.isRequired, +}; + +const StyledCategoryPieChart = styled(Box)` + width: 176px; + height: 176px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; + background: ${({ background }) => background}; + margin-right: ${({ theme }) => theme.spacing(1.5)}; +`; + +const StyledLoadingPieChart = styled(Box)` + width: 176px; + height: 176px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; + background: ${({ background }) => background}; + animation: rotate 3s linear infinite; + + @keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } + } +`; + +export default CategoryPieChart; diff --git a/modules/settings/assets/js/pages/assistant/stats/index.js b/modules/settings/assets/js/pages/assistant/stats/index.js index 8833d2e0..279d8e47 100644 --- a/modules/settings/assets/js/pages/assistant/stats/index.js +++ b/modules/settings/assets/js/pages/assistant/stats/index.js @@ -4,15 +4,14 @@ import { styled } from '@elementor/ui/styles'; import PropTypes from 'prop-types'; import PieChartLoader from '@ea11y/pages/assistant/loaders/pie-chart-loader'; import ValueLoader from '@ea11y/pages/assistant/loaders/value-loader'; +import AccessibilityAssistantStatsIssueResovledBYCategory from '@ea11y/pages/assistant/stats/issue-by-category'; import AccessibilityAssistantStatsIssueLevels from '@ea11y/pages/assistant/stats/issue-levels'; import StatsPieChart from '@ea11y/pages/assistant/stats/pie-chart'; import AccessibilityAssistantTooltip from '@ea11y/pages/assistant/tooltip'; import { __ } from '@wordpress/i18n'; +import CategoryPieChart from './category-pie-chart'; const AccessibilityAssistantStats = ({ stats, loading, noResultsState }) => { - const resolvedPercentage = stats.issues_total - ? Math.round((stats.issues_fixed / stats.issues_total) * 100) - : 0; const levelsTotal = stats.issue_levels.a + stats.issue_levels.aa + stats.issue_levels.aaa; @@ -24,16 +23,18 @@ const AccessibilityAssistantStats = ({ stats, loading, noResultsState }) => { ? Math.round((stats.issue_levels.aa / levelsTotal) * 100) : 0; + const openIssues = stats.issues_total - stats.issues_fixed; + return ( - + {__('Scanned URLs', 'pojo-accessibility')} @@ -45,55 +46,33 @@ const AccessibilityAssistantStats = ({ stats, loading, noResultsState }) => { - + - {__('Issues resolved', 'pojo-accessibility')} + {__('Open Issues', 'pojo-accessibility')} - {loading ? ( - - ) : ( - `${stats.issues_fixed}/${stats.issues_total}` - )} + {loading ? : openIssues} - - - {loading ? ( - - ) : ( - - {resolvedPercentage} - - % - - - } - firstSectorPercentage={resolvedPercentage} - /> - )} - - + - + {__('Resolved issues by level', 'pojo-accessibility')} @@ -121,6 +100,36 @@ const AccessibilityAssistantStats = ({ stats, loading, noResultsState }) => { )} + + + + + {__('Resolved issues by category', 'pojo-accessibility')} + + + + + {loading ? ( + + ) : ( + + )} + + + + + + ); }; @@ -135,18 +144,14 @@ const StyledStatsContainer = styled(Box)` margin-top: ${({ theme }) => theme.spacing(3)}; display: grid; - grid-template-columns: repeat(5, 1fr); - grid-template-rows: 1fr; - grid-column-gap: ${({ theme }) => theme.spacing(3)}; - grid-row-gap: 0; + grid-template-columns: 1fr 1fr 2fr; + grid-template-rows: 104px 176px; + grid-column-gap: ${({ theme }) => theme.spacing(2)}; + grid-row-gap: ${({ theme }) => theme.spacing(2)}; @media screen and (max-width: 960px) { - grid-template-rows: repeat(2, 1fr); - grid-row-gap: ${({ theme }) => theme.spacing(3)}; - } - - @media screen and (max-width: 705px) { - grid-template-rows: repeat(3, 1fr); + grid-template-columns: 1fr; + grid-template-rows: repeat(4, 1fr); } `; @@ -165,30 +170,18 @@ const StyledStatsItem = styled(Box)` } :nth-of-type(2) { - grid-area: 1 / 2 / 2 / 4; + grid-area: 1 / 2 / 2 / 3; } :nth-of-type(3) { - grid-area: 1 / 4 / 2 / 6; + grid-area: 2 / 1 / 3 / 3; } - @media screen and (max-width: 1200px) { - :nth-of-type(2) { - grid-area: 1 / 2 / 2 / 3; - } - - :nth-of-type(3) { - grid-area: 1 / 3 / 2 / 4; - } + :nth-of-type(4) { + grid-area: 1 / 3 / 3 / 4; } @media screen and (max-width: 960px) { - :nth-of-type(3) { - grid-area: 2 / 1 / 3 / 3; - } - } - - @media screen and (max-width: 705px) { :nth-of-type(1) { grid-area: 1 / 1 / 2 / 2; } @@ -200,12 +193,17 @@ const StyledStatsItem = styled(Box)` :nth-of-type(3) { grid-area: 3 / 1 / 4 / 2; } + + :nth-of-type(4) { + grid-area: 4 / 1 / 5 / 2; + } } `; const StyledStatsItemContent = styled(Box)` min-width: 150px; - min-height: 110px; + min-height: 50px; + height: 100%; `; const StyledStatsItemChart = styled(Box)` @@ -224,7 +222,7 @@ const StyledStatsItemTitle = styled(Typography)` align-items: center; margin: 0; - margin-bottom: ${({ theme }) => theme.spacing(2)}; + margin-bottom: ${({ spacing, theme }) => theme.spacing(spacing || 2)}; color: ${({ theme }) => theme.palette.text.primary}; font-feature-settings: diff --git a/modules/settings/assets/js/pages/assistant/stats/issue-by-category.js b/modules/settings/assets/js/pages/assistant/stats/issue-by-category.js new file mode 100644 index 00000000..0a024335 --- /dev/null +++ b/modules/settings/assets/js/pages/assistant/stats/issue-by-category.js @@ -0,0 +1,126 @@ +import Box from '@elementor/ui/Box'; +import Typography from '@elementor/ui/Typography'; +import { styled } from '@elementor/ui/styles'; +import PropTypes from 'prop-types'; +import { BLOCK_TITLES } from '@ea11y-apps/scanner/constants'; +import { __ } from '@wordpress/i18n'; + +// Override titles for specific category keys +const CATEGORY_TITLE_OVERRIDES = { + keyboardAssistiveTech: __('Keyboard/Assistive', 'pojo-accessibility'), + dynamicContent: __('Dynamic/Aria', 'pojo-accessibility'), +}; + +const AccessibilityAssistantStatsIssueResovledBYCategory = ({ + issueByCategory, +}) => { + // Process categories to show top 6 by usage + "other" + const processedCategories = () => { + // Convert to array and sort by count (descending) + const sortedCategories = Object.entries(issueByCategory || {}) + .map(([key, count]) => ({ + key, + title: CATEGORY_TITLE_OVERRIDES[key] || BLOCK_TITLES[key] || key, + count: count || 0, + })) + .sort((a, b) => b.count - a.count); + + // Calculate total issues across all categories + const totalIssues = sortedCategories.reduce( + (sum, category) => sum + category.count, + 0, + ); + + // Take top 6 categories + const top6 = sortedCategories.slice(0, 6); + // Calculate "other" count from remaining categories + const otherCount = sortedCategories + .slice(6) + .reduce((sum, category) => sum + category.count, 0); + + // Add "other" category if there are remaining categories or if it has count + const result = [...top6]; + if (otherCount > 0 || sortedCategories.length > 6) { + result.push({ + key: 'other', + title: __('Other', 'pojo-accessibility'), + count: otherCount, + }); + } + + // Convert counts to percentages + return result.map((category) => ({ + ...category, + percentage: + totalIssues > 0 ? Math.round((category.count / totalIssues) * 100) : 0, + })); + }; + + const categories = processedCategories(); + + return ( + <> + {categories.map(({ key, title, percentage }, index) => ( + + {title} + + + {percentage === 0 ? '-' : `${percentage}%`} + + + ))} + + ); +}; + +AccessibilityAssistantStatsIssueResovledBYCategory.propTypes = { + issueByCategory: PropTypes.object.isRequired, +}; + +const StyledIssueLevel = styled(Box)` + display: flex; + justify-content: flex-start; + align-items: center; + gap: ${({ theme }) => theme.spacing(1)}; + + margin-inline-start: ${({ theme }) => theme.spacing(0.5)}; + + &:not(:last-of-type) { + margin-bottom: ${({ theme }) => theme.spacing(1)}; + } + + &::before { + content: ''; + width: 10px; + height: 10px; + margin-inline-end: ${({ theme }) => theme.spacing(1)}; + border-radius: 100%; + background-color: ${({ colorIndex }) => { + const colors = [ + '#1e3a8a', // Blue 900 + '#1d4ed8', // Blue 700 + '#3b82f6', // Blue 500 + '#60a5fa', // Blue 400 + '#93c5fd', // Blue 300 + '#BFDBFE', // Blue 200 + '#DBEAFE', // Blue 100 (for "other") + ]; + return colors[colorIndex % colors.length]; + }}; + } +`; + +const StyledIssuesCount = styled(Typography)` + margin: 0; + margin-inline-start: auto; + + color: ${({ theme }) => theme.palette.text.primary}; + font-size: 14px; + font-weight: 500; + line-height: 130%; + letter-spacing: 0.1px; + min-width: 50px; + text-align: left; +`; + +export default AccessibilityAssistantStatsIssueResovledBYCategory; diff --git a/modules/settings/assets/js/pages/assistant/stats/pie-chart.js b/modules/settings/assets/js/pages/assistant/stats/pie-chart.js index b47b229a..df8fb881 100644 --- a/modules/settings/assets/js/pages/assistant/stats/pie-chart.js +++ b/modules/settings/assets/js/pages/assistant/stats/pie-chart.js @@ -1,7 +1,6 @@ import Box from '@elementor/ui/Box'; import Typography from '@elementor/ui/Typography'; -import { styled } from '@elementor/ui/styles'; -import { useTheme } from '@emotion/react'; +import { styled, useTheme } from '@elementor/ui/styles'; import PropTypes from 'prop-types'; import { __ } from '@wordpress/i18n'; @@ -17,8 +16,8 @@ const StatsPieChart = ({ return ( @@ -43,7 +42,7 @@ const StatsPieChart = ({ } const background = ` - radial-gradient(closest-side, white 79%, transparent 80% 100%), + radial-gradient(closest-side, white 77%, transparent 78% 100%), conic-gradient(${sectorColor} ${firstSectorPercentage}%, #f3f3f4 0) `; @@ -57,7 +56,7 @@ const StatsPieChart = ({ return ( theme.spacing(0.5)}; background: ${({ background }) => background}; `; diff --git a/modules/settings/assets/js/pages/pages.styles.js b/modules/settings/assets/js/pages/pages.styles.js index 9d47b8a0..456683b1 100644 --- a/modules/settings/assets/js/pages/pages.styles.js +++ b/modules/settings/assets/js/pages/pages.styles.js @@ -54,13 +54,21 @@ export const StyledStatementPaper = styled(Paper)` `; export const StyledStatementContainer = styled(Container)` - overflow: auto; - max-height: 100%; - padding: 32px; display: flex; flex-direction: column; align-items: start; - gap: 16px; + gap: ${({ theme }) => theme.spacing(2)}; + overflow: auto; + max-height: 100%; + max-width: 1200px; + width: 100%; + margin-right: auto; + margin-left: auto; + + @media (min-width: ${({ theme }) => theme.breakpoints.values.sm}px) { + padding-left: 0; + padding-right: 0; + } `; export const StyledCardContent = styled(CardContent)` diff --git a/modules/settings/module.php b/modules/settings/module.php index 11671fb6..0381d454 100644 --- a/modules/settings/module.php +++ b/modules/settings/module.php @@ -94,7 +94,7 @@ public function enqueue_scripts( $hook ) : void { EA11Y_VERSION ); - Utils\Assets::enqueue_app_assets( 'admin' ); + Utils\Assets::enqueue_app_assets( 'admin', true, [ 'wp-util', 'wp-block-editor', 'wp-components' ] ); wp_localize_script( 'admin', @@ -104,6 +104,7 @@ public function enqueue_scripts( $hook ) : void { 'planData' => Settings::get( Settings::PLAN_DATA ), 'planScope' => Settings::get( Settings::PLAN_SCOPE ), 'pluginEnv' => self::get_plugin_env(), + 'pluginVersion' => EA11Y_VERSION, 'widgetUrl' => WidgetModule::get_widget_url(), 'adminUrl' => admin_url(), 'isUrlMismatch' => ! Connect_Utils::is_valid_home_url(), @@ -525,6 +526,17 @@ public static function get_media( $url ) { return wp_remote_get( $url ); } + /** + * Hide all admin notices on the settings page + */ + public function hide_admin_notices() { + $current_screen = get_current_screen(); + if ( $current_screen && $current_screen->id === self::SETTING_PAGE_SLUG ) { + remove_all_actions( 'admin_notices' ); + remove_all_actions( 'all_admin_notices' ); + } + } + /** * Module constructor. */ @@ -538,7 +550,9 @@ public function __construct() { add_action( 'rest_api_init', [ $this, 'register_settings' ] ); add_action( 'on_connect_' . Config::APP_PREFIX . '_connected', [ $this, 'on_connect' ] ); add_action( 'current_screen', [ $this, 'check_plan_data' ] ); + add_action( 'admin_head', [ $this, 'hide_admin_notices' ] ); // Register notices - add_action( 'ea11y_register_notices', [ $this, 'register_notices' ] ); + // Removed visits quota + // add_action( 'ea11y_register_notices', [ $this, 'register_notices' ] ); } } diff --git a/modules/settings/notices/quota-100.php b/modules/settings/notices/quota-100.php index c65aec96..d636d20f 100644 --- a/modules/settings/notices/quota-100.php +++ b/modules/settings/notices/quota-100.php @@ -46,6 +46,7 @@ public function maybe_add_quota_100_notice() : void { } else { $this->conditions = false; } + } public function print_js() { diff --git a/modules/widget/components/ally-trigger.php b/modules/widget/components/ally-trigger.php index 2f48a3ef..414c37ba 100644 --- a/modules/widget/components/ally-trigger.php +++ b/modules/widget/components/ally-trigger.php @@ -1,8 +1,8 @@ - - frontend->create_action_hash( 'allyWidget:open', [] ); } } diff --git a/modules/widget/components/cache-compatibility.php b/modules/widget/components/cache-compatibility.php index ef5f0bd0..0ec67771 100644 --- a/modules/widget/components/cache-compatibility.php +++ b/modules/widget/components/cache-compatibility.php @@ -75,6 +75,20 @@ public function exclude_widget_script_handle_array( $excluded_js ) { return $excluded_js; } + /** + * wpml_home_url + * + * @param string $url + * @return string + */ + public function wpml_home_url( $url ) { + if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { + return get_site_url(); + } + + return $url; + } + public function __construct() { // WP Rocket add_filter( 'rocket_exclude_js', [ $this, 'exclude_widget_script_array' ] ); @@ -82,5 +96,7 @@ public function __construct() { // LiteSpeed Cache add_filter( 'litespeed_optimize_js_excludes', [ $this, 'exclude_widget_script_array' ] ); + // wpml support + add_filter( 'ally_connect_home_url', [ $this, 'wpml_home_url' ] ); } } diff --git a/modules/widget/components/gutenberg-link.php b/modules/widget/components/gutenberg-link.php index e0d1802d..33fc99df 100644 --- a/modules/widget/components/gutenberg-link.php +++ b/modules/widget/components/gutenberg-link.php @@ -14,7 +14,10 @@ class Gutenberg_Link { public function enqueue_custom_link_block_assets() { - Assets::enqueue_app_assets( 'gutenberg-custom-link', false ); + register_block_type( 'ally/custom-link', [] ); + if ( is_admin() ) { + Assets::enqueue_app_assets( 'gutenberg-custom-link', false ); + } } public function enqueue_custom_link_block_frontend( $block_content ) { diff --git a/modules/widget/module.php b/modules/widget/module.php index f17c118f..977b821d 100644 --- a/modules/widget/module.php +++ b/modules/widget/module.php @@ -44,12 +44,12 @@ public function enqueue_accessibility_widget() : void { true ); - wp_enqueue_style( - 'ea11y-widget-fonts', - EA11Y_ASSETS_URL . 'build/fonts.css', - [], - EA11Y_VERSION - ); + wp_enqueue_style( + 'ea11y-widget-fonts', + EA11Y_ASSETS_URL . 'build/fonts.css', + [], + EA11Y_VERSION + ); $is_analytics_enabled = AnalyticsModule::is_active(); @@ -129,52 +129,52 @@ public function enqueue_accessibility_widget_admin( $hook ) : void { plan->features ) ) { - return $widget_settings; - } - - // Check if the feature is available in the plan - foreach( $features as $feature ) { - $feature_name = str_replace( '_', '-', $feature ); - - // Assuming feature does not exist in the plan. - $feature_in_plan_data = false; - - // Check if it exists in the plan. A contingency to handle downgrading of plans. - if ( isset( $plan_data->plan->features->{$feature} ) ) { - if ($plan_data->plan->features->{$feature} ) { - $feature_in_plan_data = $plan_data->plan->features->{$feature}; - } else { - // Auto disable plan if it is set to false in the plan data. - $widget_settings[$feature_name]['enabled'] = false; - Settings::set( Settings::WIDGET_MENU_SETTINGS, $widget_settings ); - } - } else { - continue; - } - - $feature_in_widget_settings = isset( $widget_settings[$feature_name] ); - - if ( ! $feature_in_plan_data && $feature_in_widget_settings ) { - $widget_settings[$feature_name]['enabled'] = false; - } - } - - return $widget_settings; - } + /** + * Get widget's tools/menu settings + * @return array|mixed + */ + public function get_tools_settings() { + // Features to check + $features = [ 'screen_reader', 'remove_elementor_label' ]; + + // Get the data from the settings + $widget_settings = Settings::get( Settings::WIDGET_MENU_SETTINGS ); + $plan_data = Settings::get( Settings::PLAN_DATA ); + + // Return settings if features object in not present in plan data. + if ( ! isset( $plan_data->plan->features ) ) { + return $widget_settings; + } + + // Check if the feature is available in the plan + foreach ( $features as $feature ) { + $feature_name = str_replace( '_', '-', $feature ); + + // Assuming feature does not exist in the plan. + $feature_in_plan_data = false; + + // Check if it exists in the plan. A contingency to handle downgrading of plans. + if ( isset( $plan_data->plan->features->{$feature} ) ) { + if ( $plan_data->plan->features->{$feature} ) { + $feature_in_plan_data = $plan_data->plan->features->{$feature}; + } else { + // Auto disable plan if it is set to false in the plan data. + $widget_settings[ $feature_name ]['enabled'] = false; + Settings::set( Settings::WIDGET_MENU_SETTINGS, $widget_settings ); + } + } else { + continue; + } + + $feature_in_widget_settings = isset( $widget_settings[ $feature_name ] ); + + if ( ! $feature_in_plan_data && $feature_in_widget_settings ) { + $widget_settings[ $feature_name ]['enabled'] = false; + } + } + + return $widget_settings; + } /** * Remove person object from the icon settings for frontend. @@ -211,16 +211,57 @@ public function script_loader_tag( $tag, $handle, $src ) { * register_dynamic_tag * @param \Elementor\Core\DynamicTags\Manager $dynamic_tags_manager */ - function register_dynamic_tag( $dynamic_tags_manager ) { + public function register_dynamic_tag( $dynamic_tags_manager ) { $dynamic_tags_manager->register( new Components\Ally_Trigger() ); } + public function render_dynamic_tag_handler() { + ?> + + register_components(); + add_action( 'wp_footer', [ $this, 'render_dynamic_tag_handler' ] ); add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_accessibility_widget' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_accessibility_widget_admin' ] ); // Add referrer policy to widget script tag diff --git a/package-lock.json b/package-lock.json index 8fbf75b7..0502377d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "pojo-accessibility", - "version": "3.5.0", + "version": "3.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pojo-accessibility", - "version": "3.5.0", + "version": "3.6.0", "dependencies": { "@elementor/design-tokens": "^1.1.4", "@elementor/icons": "^1.46.0", - "@elementor/ui": "^1.36.0", + "@elementor/ui": "^1.36.5", "@emotion/cache": "^11.14.0", "@emotion/react": "^11.14.0", "@mui/x-charts": "^7.27.0", @@ -27,6 +27,7 @@ "@wordpress/media-utils": "^5.22.0", "@wordpress/url": "^4.10.0", "clipboard-copy": "^4.0.1", + "get-xpath": "^3.3.0", "html-react-parser": "^5.2.2", "husky": "^9.1.6", "mixpanel-browser": "^2.58.0", @@ -118,30 +119,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", - "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", - "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", + "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", + "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.4", - "@babel/parser": "^7.27.4", + "@babel/helpers": "^7.27.6", + "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", - "@babel/traverse": "^7.27.4", - "@babel/types": "^7.27.3", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -175,14 +176,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", - "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", - "dependencies": { - "@babel/parser": "^7.27.5", - "@babel/types": "^7.27.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -256,21 +257,29 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "resolve": "^1.22.10" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", @@ -434,11 +443,11 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.28.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -831,14 +840,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz", - "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -880,9 +889,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", - "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", + "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -927,17 +936,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz", - "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", + "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "globals": "^11.1.0" + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -963,12 +972,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz", - "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -1290,15 +1300,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz", - "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", + "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.3", - "@babel/plugin-transform-parameters": "^7.27.1" + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.0" }, "engines": { "node": ">=6.9.0" @@ -1355,9 +1366,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz", - "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1433,9 +1444,9 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.27.1.tgz", - "integrity": "sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1517,9 +1528,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", - "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.1.tgz", + "integrity": "sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1643,12 +1654,12 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.1.tgz", - "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", @@ -1915,26 +1926,26 @@ } }, "node_modules/@babel/traverse": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/types": "^7.28.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "version": "7.28.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", + "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" @@ -2013,6 +2024,11 @@ "@csstools/css-tokenizer": "^3.0.1" } }, + "node_modules/@date-fns/tz": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.2.0.tgz", + "integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==" + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2100,18 +2116,18 @@ "integrity": "sha512-rr8xsDDNFVbqSq+d2nGNi4VGnRb1tVHS5nvrqA0SnQAhFmF+oXp2xvSLdkdlEcXoHnW0mV+IY1ktqSYCerLUbw==" }, "node_modules/@elementor/icons": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/@elementor/icons/-/icons-1.46.0.tgz", - "integrity": "sha512-X41zzh/okGWUjbHi3+BbT3hGQnlXRMfT/agzbvlQ4vBisKE3t7E7V3LDKdP9uGeml53nSnYm9mXbuUMy9nP1zw==", + "version": "1.51.1", + "resolved": "https://registry.npmjs.org/@elementor/icons/-/icons-1.51.1.tgz", + "integrity": "sha512-33SLGISk054ebet/EelVd+bBztuqHVkrxCitLnTGxu55xEVbPVziJT6r7YYgtLkVKMRbt8iWoJ/FNuPjZ7Ke0w==", "peerDependencies": { "@elementor/ui": "^1.34.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@elementor/ui": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/@elementor/ui/-/ui-1.36.0.tgz", - "integrity": "sha512-/+SuvYceHRYazC+dLht0bgwlZQ1Qha8SZ92qbOZKJIU6vH/BeiwRZwd7OqWxPtP17XRohudhtNb6i0EmNNR7+Q==", + "version": "1.36.5", + "resolved": "https://registry.npmjs.org/@elementor/ui/-/ui-1.36.5.tgz", + "integrity": "sha512-QpnLrps5uC3Pago6JNXH67g0fhqYINKtetgMz2jZiRDzySLdZMXV5BUwLM4ak8wUkEE2e3IB0gEoZfMX5b6SNQ==", "dependencies": { "@dnd-kit/core": "6.3.1", "@dnd-kit/modifiers": "9.0.0", @@ -2294,12 +2310,13 @@ } }, "node_modules/@elementor/ui/node_modules/@mui/system/node_modules/@mui/styled-engine": { - "version": "5.16.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.14.tgz", - "integrity": "sha512-UAiMPZABZ7p8mUW4akDV6O7N3+4DatStpXMZwPlt+H/dA0lt67qawN021MNND+4QTpjaiMYxbhKZeQcyWCbuKw==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", + "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, @@ -2461,6 +2478,13 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/@elementor/ui/node_modules/date-fns-jalali": { + "version": "2.13.0-0", + "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-2.13.0-0.tgz", + "integrity": "sha512-yjlI9O18Z6ryGNagryrLO8OQ+3rishM3+A0UOX2UX10cWMn2NTlQcQ+ywTEJvF5IJz0FwX/slt2nCcpyQ/c8gw==", + "optional": true, + "peer": true + }, "node_modules/@elementor/ui/node_modules/react-is": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", @@ -2723,21 +2747,6 @@ "concat-map": "0.0.1" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2762,22 +2771,10 @@ "node": "*" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", + "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2787,28 +2784,28 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.1.tgz", - "integrity": "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", "dependencies": { - "@floating-ui/utils": "^0.2.9" + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.1.tgz", - "integrity": "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", + "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", "dependencies": { - "@floating-ui/core": "^1.7.1", - "@floating-ui/utils": "^0.2.9" + "@floating-ui/core": "^1.7.2", + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.3.tgz", - "integrity": "sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", + "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", "dependencies": { - "@floating-ui/dom": "^1.0.0" + "@floating-ui/dom": "^1.7.2" }, "peerDependencies": { "react": ">=16.8.0", @@ -2816,9 +2813,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", - "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" }, "node_modules/@formatjs/ecma402-abstract": { "version": "2.3.4", @@ -2944,14 +2941,14 @@ "dev": true }, "node_modules/@inquirer/checkbox": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.8.tgz", - "integrity": "sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.0.tgz", + "integrity": "sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, @@ -2968,13 +2965,13 @@ } }, "node_modules/@inquirer/confirm": { - "version": "5.1.12", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.12.tgz", - "integrity": "sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==", + "version": "5.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.14.tgz", + "integrity": "sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8" }, "engines": { "node": ">=18" @@ -2989,13 +2986,13 @@ } }, "node_modules/@inquirer/core": { - "version": "10.1.13", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.13.tgz", - "integrity": "sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==", + "version": "10.1.15", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.15.tgz", + "integrity": "sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==", "dev": true, "dependencies": { - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", "ansi-escapes": "^4.3.2", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", @@ -3016,13 +3013,13 @@ } }, "node_modules/@inquirer/editor": { - "version": "4.2.13", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.13.tgz", - "integrity": "sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==", + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.15.tgz", + "integrity": "sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8", "external-editor": "^3.1.0" }, "engines": { @@ -3038,13 +3035,13 @@ } }, "node_modules/@inquirer/expand": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.15.tgz", - "integrity": "sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==", + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.17.tgz", + "integrity": "sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3060,22 +3057,22 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", - "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", "dev": true, "engines": { "node": ">=18" } }, "node_modules/@inquirer/input": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.12.tgz", - "integrity": "sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.1.tgz", + "integrity": "sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8" }, "engines": { "node": ">=18" @@ -3090,13 +3087,13 @@ } }, "node_modules/@inquirer/number": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.15.tgz", - "integrity": "sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.17.tgz", + "integrity": "sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8" }, "engines": { "node": ">=18" @@ -3111,13 +3108,13 @@ } }, "node_modules/@inquirer/password": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.15.tgz", - "integrity": "sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==", + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.17.tgz", + "integrity": "sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8", "ansi-escapes": "^4.3.2" }, "engines": { @@ -3133,21 +3130,21 @@ } }, "node_modules/@inquirer/prompts": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.3.tgz", - "integrity": "sha512-8YL0WiV7J86hVAxrh3fE5mDCzcTDe1670unmJRz6ArDgN+DBK1a0+rbnNWp4DUB5rPMwqD5ZP6YHl9KK1mbZRg==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.7.1.tgz", + "integrity": "sha512-XDxPrEWeWUBy8scAXzXuFY45r/q49R0g72bUzgQXZ1DY/xEFX+ESDMkTQolcb5jRBzaNJX2W8XQl6krMNDTjaA==", "dev": true, "dependencies": { - "@inquirer/checkbox": "^4.1.8", - "@inquirer/confirm": "^5.1.12", - "@inquirer/editor": "^4.2.13", - "@inquirer/expand": "^4.0.15", - "@inquirer/input": "^4.1.12", - "@inquirer/number": "^3.0.15", - "@inquirer/password": "^4.0.15", - "@inquirer/rawlist": "^4.1.3", - "@inquirer/search": "^3.0.15", - "@inquirer/select": "^4.2.3" + "@inquirer/checkbox": "^4.2.0", + "@inquirer/confirm": "^5.1.14", + "@inquirer/editor": "^4.2.15", + "@inquirer/expand": "^4.0.17", + "@inquirer/input": "^4.2.1", + "@inquirer/number": "^3.0.17", + "@inquirer/password": "^4.0.17", + "@inquirer/rawlist": "^4.1.5", + "@inquirer/search": "^3.0.17", + "@inquirer/select": "^4.3.1" }, "engines": { "node": ">=18" @@ -3162,13 +3159,13 @@ } }, "node_modules/@inquirer/rawlist": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.3.tgz", - "integrity": "sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.5.tgz", + "integrity": "sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3184,14 +3181,14 @@ } }, "node_modules/@inquirer/search": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.15.tgz", - "integrity": "sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.17.tgz", + "integrity": "sha512-CuBU4BAGFqRYors4TNCYzy9X3DpKtgIW4Boi0WNkm4Ei1hvY9acxKdBdyqzqBCEe4YxSdaQQsasJlFlUJNgojw==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3207,14 +3204,14 @@ } }, "node_modules/@inquirer/select": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.3.tgz", - "integrity": "sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.3.1.tgz", + "integrity": "sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==", "dev": true, "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", + "@inquirer/core": "^10.1.15", + "@inquirer/figures": "^1.0.13", + "@inquirer/type": "^3.0.8", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, @@ -3231,9 +3228,9 @@ } }, "node_modules/@inquirer/type": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", - "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", + "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", "dev": true, "engines": { "node": ">=18" @@ -3678,16 +3675,12 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -3698,18 +3691,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -3717,27 +3702,24 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@keyv/serialize": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", - "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", - "dev": true, - "dependencies": { - "buffer": "^6.0.3" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", + "dev": true }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", @@ -3793,9 +3775,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.17.1.tgz", - "integrity": "sha512-OcZj+cs6EfUD39IoPBOgN61zf1XFVY+imsGoBDwXeSq2UHJZE3N59zzBOVjclck91Ne3e9gudONOeILvHCIhUA==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", + "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" @@ -3872,12 +3854,13 @@ } }, "node_modules/@mui/material/node_modules/@mui/styled-engine": { - "version": "5.16.14", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.14.tgz", - "integrity": "sha512-UAiMPZABZ7p8mUW4akDV6O7N3+4DatStpXMZwPlt+H/dA0lt67qawN021MNND+4QTpjaiMYxbhKZeQcyWCbuKw==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", + "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", "dependencies": { "@babel/runtime": "^7.23.9", "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, @@ -3903,13 +3886,13 @@ } }, "node_modules/@mui/material/node_modules/@mui/system": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.17.1.tgz", - "integrity": "sha512-aJrmGfQpyF0U4D4xYwA6ueVtQcEMebET43CUmKMP7e7iFh3sMIF3sBR0l8Urb4pqx1CBjHAaWgB0ojpND4Q3Jg==", + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", + "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", "dependencies": { "@babel/runtime": "^7.23.9", "@mui/private-theming": "^5.17.1", - "@mui/styled-engine": "^5.16.14", + "@mui/styled-engine": "^5.18.0", "@mui/types": "~7.2.15", "@mui/utils": "^5.17.1", "clsx": "^2.1.0", @@ -3997,13 +3980,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.1.1.tgz", - "integrity": "sha512-M8NbLUx+armk2ZuaxBkkMk11ultnWmrPlN0Xe3jUEaBChg/mcxa5HWIWS1EE4DF36WRACaAHVAvyekWlDQf0PQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.2.0.tgz", + "integrity": "sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==", "peer": true, "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/utils": "^7.1.1", + "@babel/runtime": "^7.27.6", + "@mui/utils": "^7.2.0", "prop-types": "^15.8.1" }, "engines": { @@ -4024,14 +4007,14 @@ } }, "node_modules/@mui/private-theming/node_modules/@mui/utils": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.1.tgz", - "integrity": "sha512-BkOt2q7MBYl7pweY2JWwfrlahhp+uGLR8S+EhiyRaofeRYUWL2YKbSGQvN4hgSN1i8poN0PaUiii1kEMrchvzg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==", "peer": true, "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/types": "^7.4.3", - "@types/prop-types": "^15.7.14", + "@babel/runtime": "^7.27.6", + "@mui/types": "^7.4.4", + "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.1.0" @@ -4069,13 +4052,13 @@ "peer": true }, "node_modules/@mui/styled-engine": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.1.1.tgz", - "integrity": "sha512-R2wpzmSN127j26HrCPYVQ53vvMcT5DaKLoWkrfwUYq3cYytL6TQrCH8JBH3z79B6g4nMZZVoaXrxO757AlShaw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.2.0.tgz", + "integrity": "sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==", "peer": true, "dependencies": { - "@babel/runtime": "^7.27.1", - "@emotion/cache": "^11.13.5", + "@babel/runtime": "^7.27.6", + "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", @@ -4103,16 +4086,16 @@ } }, "node_modules/@mui/system": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.1.1.tgz", - "integrity": "sha512-Kj1uhiqnj4Zo7PDjAOghtXJtNABunWvhcRU0O7RQJ7WOxeynoH6wXPcilphV8QTFtkKaip8EiNJRiCD+B3eROA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.2.0.tgz", + "integrity": "sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==", "peer": true, "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/private-theming": "^7.1.1", - "@mui/styled-engine": "^7.1.1", - "@mui/types": "^7.4.3", - "@mui/utils": "^7.1.1", + "@babel/runtime": "^7.27.6", + "@mui/private-theming": "^7.2.0", + "@mui/styled-engine": "^7.2.0", + "@mui/types": "^7.4.4", + "@mui/utils": "^7.2.0", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -4143,14 +4126,14 @@ } }, "node_modules/@mui/system/node_modules/@mui/utils": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.1.tgz", - "integrity": "sha512-BkOt2q7MBYl7pweY2JWwfrlahhp+uGLR8S+EhiyRaofeRYUWL2YKbSGQvN4hgSN1i8poN0PaUiii1kEMrchvzg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz", + "integrity": "sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==", "peer": true, "dependencies": { - "@babel/runtime": "^7.27.1", - "@mui/types": "^7.4.3", - "@types/prop-types": "^15.7.14", + "@babel/runtime": "^7.27.6", + "@mui/types": "^7.4.4", + "@types/prop-types": "^15.7.15", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.1.0" @@ -4188,11 +4171,11 @@ "peer": true }, "node_modules/@mui/types": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.3.tgz", - "integrity": "sha512-2UCEiK29vtiZTeLdS2d4GndBKacVyxGvReznGXGr+CzW/YhjIX+OHUdCIczZjzcRAgKBGmE9zCIgoV9FleuyRQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz", + "integrity": "sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==", "dependencies": { - "@babel/runtime": "^7.27.1" + "@babel/runtime": "^7.27.6" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -4372,156 +4355,717 @@ "node": ">= 8" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", "dev": true, - "hasInstallScript": true, - "optional": true, "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" + "node": ">=14" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", "dev": true, - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">= 10.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], + "node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/core/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": ">=14" } }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], + "node_modules/@opentelemetry/instrumentation": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz", + "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.46.1.tgz", + "integrity": "sha512-AyXVnlCf/xV3K/rNumzKxZqsULyITJH6OVLiW6730JPRqWA7Zc9bvYoVNpN6iOpTU8CasH34SU/ksVJmObFibQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=14" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.43.1.tgz", + "integrity": "sha512-ht7YGWQuV5BopMcw5Q2hXn3I8eG8TH0J/kc/GMcW4CuNTgiP6wCu44BOnucJWL3CmFWaRHI//vWyAhaC8BwePw==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.16.1.tgz", + "integrity": "sha512-K/qU4CjnzOpNkkKO4DfCLSQshejRNAJtd4esgigo/50nxCB6XCyi1dhAblUHM9jG5dRm8eu0FB+t87nIo99LYQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.47.1.tgz", + "integrity": "sha512-QNXPTWteDclR2B4pDFpz0TNghgB33UMjUt14B+BZPmtH1MwUFAfLHBaP5If0Z5NZC+jaH8oF2glgYjrmhZWmSw==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.19.1.tgz", + "integrity": "sha512-6g0FhB3B9UobAR60BGTcXg4IHZ6aaYJzp0Ki5FhnxyAPt8Ns+9SSvgcrnsN2eGmk3RWG5vYycUGOEApycQL24A==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.43.1.tgz", + "integrity": "sha512-M6qGYsp1cURtvVLGDrPPZemMFEbuMmCXgQYTReC/IbimV5sGrLBjB+/hANUpRZjX67nGLdKSVLZuQQAiNz+sww==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.47.1.tgz", + "integrity": "sha512-EGQRWMGqwiuVma8ZLAZnExQ7sBvbOx0N/AE/nlafISPs8S+QtXX+Viy6dcQwVWwYHQPAcuY3bFt3xgoAwb4ZNQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.45.2.tgz", + "integrity": "sha512-7Ehow/7Wp3aoyCrZwQpU7a2CnoMq0XhIcioFuKjBb0PLYfBfmTsFTUyatlHu0fRxhwcRsSQRTvEhmZu8CppBpQ==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.57.2.tgz", + "integrity": "sha512-1Uz5iJ9ZAlFOiPuwYg29Bf7bJJc/GeoeJIFKJYQf67nTVKFe8RHbEtxgkOmK4UGZNHKXcpW4P8cWBYzBn1USpg==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "0.57.2", + "@opentelemetry/semantic-conventions": "1.28.0", + "forwarded-parse": "2.1.2", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.47.1.tgz", + "integrity": "sha512-OtFGSN+kgk/aoKgdkKQnBsQFDiG8WdCxu+UrHr0bXScdAmtSzLSraLo7wFIb25RVHfRWvzI5kZomqJYEg/l1iA==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.7.1.tgz", + "integrity": "sha512-OtjaKs8H7oysfErajdYr1yuWSjMAectT7Dwr+axIoZqT9lmEOkD/H/3rgAs8h/NIuEi2imSXD+vL4MZtOuJfqQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.44.1.tgz", + "integrity": "sha512-U4dQxkNhvPexffjEmGwCq68FuftFK15JgUF05y/HlK3M6W/G2iEaACIfXdSnwVNe9Qh0sPfw8LbOPxrWzGWGMQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.47.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.47.1.tgz", + "integrity": "sha512-l/c+Z9F86cOiPJUllUCt09v+kICKvT+Vg1vOAJHtHPsJIzurGayucfCMq2acd/A/yxeNWunl9d9eqZ0G+XiI6A==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.44.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.44.1.tgz", + "integrity": "sha512-5MPkYCvG2yw7WONEjYj5lr5JFehTobW7wX+ZUFy81oF2lr9IPfZk9qO+FTaM0bGEiymwfLwKe6jE15nHn1nmHg==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.52.0.tgz", + "integrity": "sha512-1xmAqOtRUQGR7QfJFfGV/M2kC7wmI2WgZdpru8hJl3S0r4hW0n3OQpEHlSGXJAaNFyvT+ilnwkT+g5L4ljHR6g==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.1.tgz", + "integrity": "sha512-3kINtW1LUTPkiXFRSSBmva1SXzS/72we/jL22N+BnF3DFcoewkdkHPYOIdAAk9gSicJ4d5Ojtt1/HeibEc5OQg==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.45.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.1.tgz", + "integrity": "sha512-TKp4hQ8iKQsY7vnp/j0yJJ4ZsP109Ht6l4RHTj0lNEG1TfgTrIH5vJMbgmoYXWzNHAqBH2e7fncN12p3BP8LFg==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/mysql": "2.15.26" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.45.2.tgz", + "integrity": "sha512-h6Ad60FjCYdJZ5DTz1Lk2VmQsShiViKe0G7sYikb0GHI0NVvApp2XQNRHNjEMz87roFttGPLHOYVPlfy+yVIhQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.51.1.tgz", + "integrity": "sha512-QxgjSrxyWZc7Vk+qGSfsejPVFL1AgAJdSBMYZdDUbwg730D09ub3PXScB9d04vIqPriZ+0dqzjmQx0yWKiCi2Q==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.26.0", + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@opentelemetry/sql-common": "^0.40.1", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.6" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis-4": { + "version": "0.46.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis-4/-/instrumentation-redis-4-0.46.1.tgz", + "integrity": "sha512-UMqleEoabYMsWoTkqyt9WAzXwZ4BlFZHO40wr3d5ZvtjKCHlD4YXLm+6OLCeIi/HkX7EXvQaz8gtAwkwwSEvcQ==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/redis-common": "^0.36.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.18.1.tgz", + "integrity": "sha512-5Cuy/nj0HBaH+ZJ4leuD7RjgvA844aY2WW+B5uLcWtxGjRZl3MNLuxnNg5DYWZNPO+NafSSnra0q49KWAHsKBg==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.57.1", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.10.1.tgz", + "integrity": "sha512-rkOGikPEyRpMCmNu9AQuV5dtRlDmJp2dK5sw8roVshAGoB6hH/3QjDtRhdwd75SsJwgynWUNRUYe0wAkTo16tQ==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.36.2.tgz", + "integrity": "sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.36.0.tgz", + "integrity": "sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.1.tgz", + "integrity": "sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" }, "funding": { "type": "opencollective", @@ -4669,9 +5213,9 @@ } }, "node_modules/@paulirish/trace_engine": { - "version": "0.0.53", - "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.53.tgz", - "integrity": "sha512-PUl/vlfo08Oj804VI5nDPeSk9vyslnBlVzDDwFt8SUVxY8+KdGMkra/vrXjEEHe8gb7+RqVTfOIlGw0nyrEelA==", + "version": "0.0.57", + "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.57.tgz", + "integrity": "sha512-s+JNJ53B1MiEqCOD2hnK96wFTRRStxFmtm6QaIe2jiNI+lkS9mYEgnHOH2caQ/dEPn6wY+f2u5dW6aFYjmbaiw==", "dev": true, "dependencies": { "legacy-javascript": "latest", @@ -4689,9 +5233,9 @@ } }, "node_modules/@pkgr/core": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", - "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "dev": true, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -4701,13 +5245,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.0.tgz", - "integrity": "sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==", + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.54.1.tgz", + "integrity": "sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw==", "dev": true, "peer": true, "dependencies": { - "playwright": "1.53.0" + "playwright": "1.54.1" }, "bin": { "playwright": "cli.js" @@ -4717,9 +5261,9 @@ } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.16.tgz", - "integrity": "sha512-kLQc9xz6QIqd2oIYyXRUiAp79kGpFBm3fEM9ahfG1HI0WI5gdZ2OVHWdmZYnwODt7ISck+QuQ6sBPrtvUBML7Q==", + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz", + "integrity": "sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ==", "dev": true, "dependencies": { "ansi-html": "^0.0.9", @@ -4788,6 +5332,18 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@prisma/instrumentation": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.11.1.tgz", + "integrity": "sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==", + "dev": true, + "dependencies": { + "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, "node_modules/@puppeteer/browsers": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.6.1.tgz", @@ -5238,83 +5794,101 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "dev": true }, - "node_modules/@sentry-internal/tracing": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.3.tgz", - "integrity": "sha512-Ausx+Jw1pAMbIBHStoQ6ZqDZR60PsCByvHdw/jdH9AqPrNE9xlBSf9EwcycvmrzwyKspSLaB52grlje2cRIUMg==", - "dev": true, - "dependencies": { - "@sentry/core": "7.120.3", - "@sentry/types": "7.120.3", - "@sentry/utils": "7.120.3" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@sentry/core": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.3.tgz", - "integrity": "sha512-vyy11fCGpkGK3qI5DSXOjgIboBZTriw0YDx/0KyX5CjIjDDNgp5AGgpgFkfZyiYiaU2Ww3iFuKo4wHmBusz1uA==", + "version": "9.40.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.40.0.tgz", + "integrity": "sha512-cZkuz6BDna6VXSqvlWnrRsaDx4QBKq1PcfQrqhVz8ljs0M7Gcl+Mtj8dCzUxx12fkYM62hQXG72DEGNlAQpH/Q==", "dev": true, - "dependencies": { - "@sentry/types": "7.120.3", - "@sentry/utils": "7.120.3" - }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@sentry/integrations": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.3.tgz", - "integrity": "sha512-6i/lYp0BubHPDTg91/uxHvNui427df9r17SsIEXa2eKDwQ9gW2qRx5IWgvnxs2GV/GfSbwcx4swUB3RfEWrXrQ==", - "dev": true, - "dependencies": { - "@sentry/core": "7.120.3", - "@sentry/types": "7.120.3", - "@sentry/utils": "7.120.3", - "localforage": "^1.8.1" + "node_modules/@sentry/node": { + "version": "9.40.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-9.40.0.tgz", + "integrity": "sha512-8bVWChXzGH4QmbVw+H/yiJ6zxqPDhnx11fEAP+vpL1UBm1cAV67CoB4eS7OqQdPC8gF/BQb2sqF0TvY/12NPpA==", + "dev": true, + "dependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1", + "@opentelemetry/core": "^1.30.1", + "@opentelemetry/instrumentation": "^0.57.2", + "@opentelemetry/instrumentation-amqplib": "^0.46.1", + "@opentelemetry/instrumentation-connect": "0.43.1", + "@opentelemetry/instrumentation-dataloader": "0.16.1", + "@opentelemetry/instrumentation-express": "0.47.1", + "@opentelemetry/instrumentation-fs": "0.19.1", + "@opentelemetry/instrumentation-generic-pool": "0.43.1", + "@opentelemetry/instrumentation-graphql": "0.47.1", + "@opentelemetry/instrumentation-hapi": "0.45.2", + "@opentelemetry/instrumentation-http": "0.57.2", + "@opentelemetry/instrumentation-ioredis": "0.47.1", + "@opentelemetry/instrumentation-kafkajs": "0.7.1", + "@opentelemetry/instrumentation-knex": "0.44.1", + "@opentelemetry/instrumentation-koa": "0.47.1", + "@opentelemetry/instrumentation-lru-memoizer": "0.44.1", + "@opentelemetry/instrumentation-mongodb": "0.52.0", + "@opentelemetry/instrumentation-mongoose": "0.46.1", + "@opentelemetry/instrumentation-mysql": "0.45.1", + "@opentelemetry/instrumentation-mysql2": "0.45.2", + "@opentelemetry/instrumentation-pg": "0.51.1", + "@opentelemetry/instrumentation-redis-4": "0.46.1", + "@opentelemetry/instrumentation-tedious": "0.18.1", + "@opentelemetry/instrumentation-undici": "0.10.1", + "@opentelemetry/resources": "^1.30.1", + "@opentelemetry/sdk-trace-base": "^1.30.1", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@prisma/instrumentation": "6.11.1", + "@sentry/core": "9.40.0", + "@sentry/node-core": "9.40.0", + "@sentry/opentelemetry": "9.40.0", + "import-in-the-middle": "^1.14.2", + "minimatch": "^9.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@sentry/node": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.120.3.tgz", - "integrity": "sha512-t+QtekZedEfiZjbkRAk1QWJPnJlFBH/ti96tQhEq7wmlk3VszDXraZvLWZA0P2vXyglKzbWRGkT31aD3/kX+5Q==", + "node_modules/@sentry/node-core": { + "version": "9.40.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-9.40.0.tgz", + "integrity": "sha512-97JONDa8NxItX0Cz5WQPMd1gQjzodt38qQ0OzZNFvYg2Cpvxob8rxwsNA08Liu7B97rlvsvqMt+Wbgw8SAMfgQ==", "dev": true, "dependencies": { - "@sentry-internal/tracing": "7.120.3", - "@sentry/core": "7.120.3", - "@sentry/integrations": "7.120.3", - "@sentry/types": "7.120.3", - "@sentry/utils": "7.120.3" + "@sentry/core": "9.40.0", + "@sentry/opentelemetry": "9.40.0", + "import-in-the-middle": "^1.14.2" }, "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/types": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.3.tgz", - "integrity": "sha512-C4z+3kGWNFJ303FC+FxAd4KkHvxpNFYAFN8iMIgBwJdpIl25KZ8Q/VdGn0MLLUEHNLvjob0+wvwlcRBBNLXOow==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" } }, - "node_modules/@sentry/utils": { - "version": "7.120.3", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.3.tgz", - "integrity": "sha512-UDAOQJtJDxZHQ5Nm1olycBIsz2wdGX8SdzyGVHmD8EOQYAeDZQyIlQYohDe9nazdIOQLZCIc3fU0G9gqVLkaGQ==", + "node_modules/@sentry/opentelemetry": { + "version": "9.40.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-9.40.0.tgz", + "integrity": "sha512-POQ/ZFmBbi15z3EO9gmTExpxCfW0Ug+WooA8QZPJaizo24gcF5AMOgwuGFwT2YLw/2HdPWjPUPujNNGdCWM6hw==", "dev": true, "dependencies": { - "@sentry/types": "7.120.3" + "@sentry/core": "9.40.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0", + "@opentelemetry/core": "^1.30.1 || ^2.0.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0", + "@opentelemetry/semantic-conventions": "^1.34.0" } }, "node_modules/@sideway/address": { @@ -5375,19 +5949,19 @@ } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.2.tgz", - "integrity": "sha512-tylFJGMQo62alGazK74MNxFjMagYOHmBZiePZFOJK2n13JZta0uVkB3Bh5qodUmOLtRH+uxH297EibK14UKm8g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.3.tgz", + "integrity": "sha512-85fsmzgsIVmyG3/GFrjuYj6Cz8rAM7IZiPiXCMiSMfoDOC1lOrzrXPDk24WqviAghnPqGpx8b0caK2PuewWGFg==", "dev": true, "dependencies": { "@csstools/css-parser-algorithms": "^3.0.1", "@csstools/css-tokenizer": "^3.0.1", "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", + "postcss": "^8.4.41", "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", - "style-search": "^0.1.0", - "stylelint": "^16.8.2" + "style-search": "^0.1.0" }, "engines": { "node": "^18.12 || >=20.9" @@ -5780,6 +6354,11 @@ "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.1.0.tgz", "integrity": "sha512-oocsqY7g0cR+Gur5jRQLSrX2OtpMLMse1I10JQBm8CdGMrDkh1Mg2gjsiquMHRtBs4Qwu5wgEp5GgIYHk4SNPw==" }, + "node_modules/@tannin/sprintf": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@tannin/sprintf/-/sprintf-1.3.1.tgz", + "integrity": "sha512-3auu6Wqm4TR6gvOh1Dgh1d2k9+arNmu3T0JLiUJoJMgayeHr450OuWeZIMTE4CUuq51rwn/NI9S5InT0JuTxQw==" + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -5983,9 +6562,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", - "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.7.tgz", + "integrity": "sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==", "dev": true, "dependencies": { "@types/node": "*", @@ -6119,10 +6698,14 @@ "dev": true }, "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-6.0.0.tgz", + "integrity": "sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==", + "deprecated": "This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "minimatch": "*" + } }, "node_modules/@types/minimist": { "version": "1.2.5", @@ -6135,18 +6718,27 @@ "resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.15.tgz", "integrity": "sha512-qL0hyIMNPow317QWW/63RvL1x5MVMV+Ru3NaY9f/CuEpCqrmb7WeuK2071ZY5hczOnm38qExWM2i2WtkXLSqFw==" }, + "node_modules/@types/mysql": { + "version": "2.15.26", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.26.tgz", + "integrity": "sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { - "version": "24.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", - "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", + "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==", "dependencies": { "undici-types": "~7.8.0" } }, "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.13.tgz", + "integrity": "sha512-zePQJSW5QkwSHKRApqWCVKeKoSOt4xvEnLENZPjyvm9Ezdf/EyDeJM7jqLzOwjVICQQzvLZ63T55MKdJB5H6ww==", "dev": true, "dependencies": { "@types/node": "*" @@ -6163,6 +6755,26 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz", + "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==", + "dev": true, + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/prop-types": { "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", @@ -6256,6 +6868,12 @@ "@types/send": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz", + "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==", + "dev": true + }, "node_modules/@types/simple-peer": { "version": "9.11.8", "resolved": "https://registry.npmjs.org/@types/simple-peer/-/simple-peer-9.11.8.tgz", @@ -6291,6 +6909,15 @@ "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==", "dev": true }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -6842,21 +7469,66 @@ } } }, - "node_modules/@wordpress/a11y": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.25.0.tgz", - "integrity": "sha512-9wJZC7gWUrDN1Ybch6pgGZL73kSm2b4dm9YDJtNJuCa/6T7TkVRVdpjVtnTLhvATPSXNV81P/bLK8fWbI3ze0A==", + "node_modules/@wordpress/a11y": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.27.0.tgz", + "integrity": "sha512-wbZ7F4mA2VZKGkA30fivJwHT6OA+CXzhGokaaIVGWqjAygioFkaqb49u+eMWKTQoYEL6BdeUgDmViMUxva73Uw==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/dom-ready": "^4.27.0", + "@wordpress/i18n": "^6.0.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/a11y/node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@wordpress/a11y/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/api-fetch": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.27.0.tgz", + "integrity": "sha512-YoYWIJg087pXSWaiiNAKixUB70l1gbvZi0VEj6SrqdAItuTfYelG6hJtYxF2xPhBWVGbTXaq8nJMVRB8EcutAg==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/dom-ready": "^4.25.0", - "@wordpress/i18n": "^5.25.0" + "@wordpress/i18n": "^6.0.0", + "@wordpress/url": "^4.27.0" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" } }, - "node_modules/@wordpress/a11y/node_modules/@babel/runtime": { + "node_modules/@wordpress/api-fetch/node_modules/@babel/runtime": { "version": "7.25.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", @@ -6867,35 +7539,30 @@ "node": ">=6.9.0" } }, - "node_modules/@wordpress/api-fetch": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.25.0.tgz", - "integrity": "sha512-UrZWfx62/NaTitn+1HqQ8IFe+D5Y7+R7AHs0ag8KKsoKi/7cczm9MK3jgXwtjBZ0X6vbwOzxrdcTbMuPyymc0g==", + "node_modules/@wordpress/api-fetch/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/i18n": "^5.25.0", - "@wordpress/url": "^4.25.0" + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" } }, - "node_modules/@wordpress/api-fetch/node_modules/@babel/runtime": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", - "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@wordpress/autop": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.25.0.tgz", - "integrity": "sha512-MCTZYyNkUSqyZFfi3UY+Piiyzp5p2y1rkT1FB3+8ZVbigpRid4AnwO5zfsFFAUbbPCK/Z5aP1J0WP1lxnmBRIg==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.27.0.tgz", + "integrity": "sha512-UY1bxt8aJcZfG0U7y28QiHJAt6ZEv5gk7by9IZQ8VJ4bUEdNAafyWr9ysJlERDsca+CK2xNIR/JwQb7CAaXNjw==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -6916,9 +7583,9 @@ } }, "node_modules/@wordpress/babel-preset-default": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-8.25.0.tgz", - "integrity": "sha512-8Sf4pkH7/4pcKt/jOkVNLOoScypMOM2xEHtyiTE5tHgX4z7UZRNbXFKqJ9fxDDb/cniDdNyeG5QhOLIZbO7hlg==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-8.27.0.tgz", + "integrity": "sha512-FzfXQL/DAlNrOeiz88p0ReV1TLofo0vWZfQOdd7OswwzfYsMlXue7ms7Qo23z8tag+nNYnqQp71atUD5vox+fg==", "dev": true, "dependencies": { "@babel/core": "7.25.7", @@ -6927,8 +7594,8 @@ "@babel/preset-env": "7.25.7", "@babel/preset-typescript": "7.25.7", "@babel/runtime": "7.25.7", - "@wordpress/browserslist-config": "^6.25.0", - "@wordpress/warning": "^3.25.0", + "@wordpress/browserslist-config": "^6.27.0", + "@wordpress/warning": "^3.27.0", "browserslist": "^4.21.10", "core-js": "^3.31.0", "react": "^18.3.0" @@ -6981,9 +7648,9 @@ } }, "node_modules/@wordpress/base-styles": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-6.1.0.tgz", - "integrity": "sha512-5AC4M7jXQaSknrSiuBbUWJa00jYr6i3yABf93VFuVzy9QGZQTvupQo2/bi6uAZ98pDruniScrnJJq8UG6JsoJQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/base-styles/-/base-styles-6.3.0.tgz", + "integrity": "sha512-Xu7hDd95c96zOk/gAvANlSWFRl6YEduyjc2sN4pSwCM7zHIgwBELdLg9CyzgwuR7Y3XDNdBgptsS9OUHBiC22Q==", "dev": true, "engines": { "node": ">=18.12.0", @@ -6991,9 +7658,9 @@ } }, "node_modules/@wordpress/blob": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.25.0.tgz", - "integrity": "sha512-M89TPVhqgKXDKEmMB+DssC0CqGPOLOrKEtVI2tJQH4Br/HGgWJ7tAQF9rtYKuQVFALKX6vkNIPcX9WEd+7p/kw==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.27.0.tgz", + "integrity": "sha512-dOXMP3xR6nJMGsDQbQ+IbJBjyVZq9RK0e7jA6elbkuspEQmRkbyiyfWTuscSEusJydW6NDRaQl9rzQsbLy7UeA==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7014,46 +7681,46 @@ } }, "node_modules/@wordpress/block-editor": { - "version": "14.20.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.20.0.tgz", - "integrity": "sha512-OhgsU3zONY4FHH3O4e5SZrqZDPI2FZHt6bROUknSc3nvFyhEojuq6ELtcQFsywhJyiWg3wN9TTz97N1LvreF2g==", + "version": "14.21.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.21.0.tgz", + "integrity": "sha512-twVFO5I+go/S2a6xxuxxrWlC9G3AZKiLtSgeZ+R0kuCfeyZgw49vCwQixDzJWBmpCagAYTEeakFv3PAkbMLaMA==", "dependencies": { "@babel/runtime": "7.25.7", "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.25.0", - "@wordpress/api-fetch": "^7.25.0", - "@wordpress/blob": "^4.25.0", - "@wordpress/block-serialization-default-parser": "^5.25.0", - "@wordpress/blocks": "^14.14.0", - "@wordpress/commands": "^1.25.0", - "@wordpress/components": "^29.11.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/date": "^5.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/dom": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/escape-html": "^3.25.0", - "@wordpress/hooks": "^4.25.0", - "@wordpress/html-entities": "^4.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/icons": "^10.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/keyboard-shortcuts": "^5.25.0", - "@wordpress/keycodes": "^4.25.0", - "@wordpress/notices": "^5.25.0", - "@wordpress/preferences": "^4.25.0", - "@wordpress/priority-queue": "^3.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/rich-text": "^7.25.0", - "@wordpress/style-engine": "^2.25.0", - "@wordpress/token-list": "^3.25.0", - "@wordpress/upload-media": "^0.10.0", - "@wordpress/url": "^4.25.0", - "@wordpress/warning": "^3.25.0", - "@wordpress/wordcount": "^4.25.0", + "@wordpress/a11y": "^4.26.0", + "@wordpress/api-fetch": "^7.26.0", + "@wordpress/blob": "^4.26.0", + "@wordpress/block-serialization-default-parser": "^5.26.0", + "@wordpress/blocks": "^14.15.0", + "@wordpress/commands": "^1.26.0", + "@wordpress/components": "^29.12.0", + "@wordpress/compose": "^7.26.0", + "@wordpress/data": "^10.26.0", + "@wordpress/date": "^5.26.0", + "@wordpress/deprecated": "^4.26.0", + "@wordpress/dom": "^4.26.0", + "@wordpress/element": "^6.26.0", + "@wordpress/escape-html": "^3.26.0", + "@wordpress/hooks": "^4.26.0", + "@wordpress/html-entities": "^4.26.0", + "@wordpress/i18n": "^5.26.0", + "@wordpress/icons": "^10.26.0", + "@wordpress/is-shallow-equal": "^5.26.0", + "@wordpress/keyboard-shortcuts": "^5.26.0", + "@wordpress/keycodes": "^4.26.0", + "@wordpress/notices": "^5.26.0", + "@wordpress/preferences": "^4.26.0", + "@wordpress/priority-queue": "^3.26.0", + "@wordpress/private-apis": "^1.26.0", + "@wordpress/rich-text": "^7.26.0", + "@wordpress/style-engine": "^2.26.0", + "@wordpress/token-list": "^3.26.0", + "@wordpress/upload-media": "^0.11.0", + "@wordpress/url": "^4.26.0", + "@wordpress/warning": "^3.26.0", + "@wordpress/wordcount": "^4.26.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", @@ -7098,9 +7765,9 @@ } }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.25.0.tgz", - "integrity": "sha512-tQWAbTY/5Rsv5H544qV7JEq5sjVfXFWiZSrXdb4Tnhs2K40LbJEKuYBcnJXo99zh0UHcX3Gw2h3qIBLSCaLC4A==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.27.0.tgz", + "integrity": "sha512-OTGiQMjailRi4KEM/9WNdUcZqUK2YRXf4Zd1VfsOPGI6RaZbYwW/5p0KuWOKYAVNF2ALAhssOoqxjKCvBs0kwg==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7121,26 +7788,26 @@ } }, "node_modules/@wordpress/blocks": { - "version": "14.14.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-14.14.0.tgz", - "integrity": "sha512-3SbR/wM7u7TyQLs+Bw98dL+T0Q4DX+JMY9NXNb5yPkm/K2tuvNzRm/9xQmbfU+xHvop+3mDA8uzf3ROQUaE9Dw==", + "version": "14.15.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-14.15.0.tgz", + "integrity": "sha512-Esy7gM2HG3iimcFHFnwtXnIw0TLcSxT8bAe/S48wxZCIqM3++xoRgrEGe55u/d6Oj0mRM9HRFdp9et92nEsGBQ==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/autop": "^4.25.0", - "@wordpress/blob": "^4.25.0", - "@wordpress/block-serialization-default-parser": "^5.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/dom": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/hooks": "^4.25.0", - "@wordpress/html-entities": "^4.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/rich-text": "^7.25.0", - "@wordpress/shortcode": "^4.25.0", - "@wordpress/warning": "^3.25.0", + "@wordpress/autop": "^4.26.0", + "@wordpress/blob": "^4.26.0", + "@wordpress/block-serialization-default-parser": "^5.26.0", + "@wordpress/data": "^10.26.0", + "@wordpress/deprecated": "^4.26.0", + "@wordpress/dom": "^4.26.0", + "@wordpress/element": "^6.26.0", + "@wordpress/hooks": "^4.26.0", + "@wordpress/html-entities": "^4.26.0", + "@wordpress/i18n": "^5.26.0", + "@wordpress/is-shallow-equal": "^5.26.0", + "@wordpress/private-apis": "^1.26.0", + "@wordpress/rich-text": "^7.26.0", + "@wordpress/shortcode": "^4.26.0", + "@wordpress/warning": "^3.26.0", "change-case": "^4.1.2", "colord": "^2.7.0", "fast-deep-equal": "^3.1.3", @@ -7173,9 +7840,9 @@ } }, "node_modules/@wordpress/browserslist-config": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-6.25.0.tgz", - "integrity": "sha512-pJdhs1KJES46Z7/EFA4clmXlc+BBMlDrtFjoBX1FC5Lqh4RfJ1YD7VGdMSSuQpCF2iIrU4AijR31AZQ8NOy5mQ==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-6.27.0.tgz", + "integrity": "sha512-lBl7ggE05IF3jp3USh2xaz/OnaO1dj4HaySGXXD56Z9ikRcmneyjiux3UmzeHYPPp00XXOcjZ7xGIMXQJOq2BQ==", "dev": true, "engines": { "node": ">=18.12.0", @@ -7183,18 +7850,18 @@ } }, "node_modules/@wordpress/commands": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.25.0.tgz", - "integrity": "sha512-guWyoJPwWIw148fS2YpM+iEFuq9HMBOnSY5XPxpOQOTsQlRqolKlyiPp8D1SI5R2zdBHvEGAkpzcMo2woRRUcQ==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.27.0.tgz", + "integrity": "sha512-W3cXIh/9SyEPGUgjIDit+xu0pLXXfcoD47afTgCyx48MNWxUx9ml+vpk5W5eFmQBTbzTVrMq7krlgHrbOhifZw==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/components": "^29.11.0", - "@wordpress/data": "^10.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/icons": "^10.25.0", - "@wordpress/keyboard-shortcuts": "^5.25.0", - "@wordpress/private-apis": "^1.25.0", + "@wordpress/components": "^30.0.0", + "@wordpress/data": "^10.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/keyboard-shortcuts": "^5.27.0", + "@wordpress/private-apis": "^1.27.0", "clsx": "^2.1.1", "cmdk": "^1.0.0" }, @@ -7218,6 +7885,99 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/commands/node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@wordpress/commands/node_modules/@wordpress/components": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-30.0.0.tgz", + "integrity": "sha512-+9A36VLY6jz6TYmfDHzOWCYVz/wJQFBWZwfZmET8ce9yUKjeIQ+Zhhihj/EbTmmqSvZIgEgqinXTnnqCJr1OTA==", + "dependencies": { + "@ariakit/react": "^0.4.15", + "@babel/runtime": "7.25.7", + "@emotion/cache": "^11.7.1", + "@emotion/css": "^11.7.1", + "@emotion/react": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/styled": "^11.6.0", + "@emotion/utils": "^1.0.0", + "@floating-ui/react-dom": "2.0.8", + "@types/gradient-parser": "0.1.3", + "@types/highlight-words-core": "1.2.1", + "@use-gesture/react": "^10.3.1", + "@wordpress/a11y": "^4.27.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/date": "^5.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/escape-html": "^3.27.0", + "@wordpress/hooks": "^4.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/keycodes": "^4.27.0", + "@wordpress/primitives": "^4.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/warning": "^3.27.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.1.9", + "gradient-parser": "1.0.2", + "highlight-words-core": "^1.2.2", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "path-to-regexp": "^6.2.1", + "re-resizable": "^6.4.0", + "react-colorful": "^5.3.1", + "react-day-picker": "^9.7.0", + "remove-accents": "^0.5.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/commands/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/commands/node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -7227,9 +7987,9 @@ } }, "node_modules/@wordpress/components": { - "version": "29.11.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-29.11.0.tgz", - "integrity": "sha512-p/hicoCxHo4uC5DeGsdLme/JcRwedFkNctKS7uo5dy05odWXWOPDLiSsWYz6F7uCKbmBJNucxdF3f42YTh6y1Q==", + "version": "29.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-29.12.0.tgz", + "integrity": "sha512-jE96pUj84OZya54VusRdEIdTiLjbe2Qst3GbHZcQpA5GiSkPBmGjKWpO6FxR7kRDT4GMnZoVxgtV6xJk4IaNQw==", "dependencies": { "@ariakit/react": "^0.4.15", "@babel/runtime": "7.25.7", @@ -7243,23 +8003,23 @@ "@types/gradient-parser": "0.1.3", "@types/highlight-words-core": "1.2.1", "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.25.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/date": "^5.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/dom": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/escape-html": "^3.25.0", - "@wordpress/hooks": "^4.25.0", - "@wordpress/html-entities": "^4.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/icons": "^10.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/keycodes": "^4.25.0", - "@wordpress/primitives": "^4.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/rich-text": "^7.25.0", - "@wordpress/warning": "^3.25.0", + "@wordpress/a11y": "^4.26.0", + "@wordpress/compose": "^7.26.0", + "@wordpress/date": "^5.26.0", + "@wordpress/deprecated": "^4.26.0", + "@wordpress/dom": "^4.26.0", + "@wordpress/element": "^6.26.0", + "@wordpress/escape-html": "^3.26.0", + "@wordpress/hooks": "^4.26.0", + "@wordpress/html-entities": "^4.26.0", + "@wordpress/i18n": "^5.26.0", + "@wordpress/icons": "^10.26.0", + "@wordpress/is-shallow-equal": "^5.26.0", + "@wordpress/keycodes": "^4.26.0", + "@wordpress/primitives": "^4.26.0", + "@wordpress/private-apis": "^1.26.0", + "@wordpress/rich-text": "^7.26.0", + "@wordpress/warning": "^3.26.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", @@ -7306,19 +8066,19 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.25.0.tgz", - "integrity": "sha512-nfjtMZgrhdHU8/zOLUyA5o8ShLot1vbHZ0I2+IxLyNskRMVyR9pm4BAJSYKJ9XqBUom2/N51gfeKg5uhd9Y0TQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.27.0.tgz", + "integrity": "sha512-87/V/hyyg2Fojfk0hDVR4U3vdDdbNWoVdf17QnAORYt35lWWTxwMBKlZqIhFEuoLrPTvMQvu6ecjhxFNYB+ALg==", "dependencies": { "@babel/runtime": "7.25.7", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/dom": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/keycodes": "^4.25.0", - "@wordpress/priority-queue": "^3.25.0", - "@wordpress/undo-manager": "^1.25.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/keycodes": "^4.27.0", + "@wordpress/priority-queue": "^3.27.0", + "@wordpress/undo-manager": "^1.27.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -7344,27 +8104,27 @@ } }, "node_modules/@wordpress/core-data": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.25.0.tgz", - "integrity": "sha512-CgSB4Po7Gx0l44y/Ted0nwla1hQF7NP6wChECQDv/CLYA/05OeNm/xjURbmUTM9jZTRFZIn0ACUqNbZCy8/E+g==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.27.0.tgz", + "integrity": "sha512-NK8Bqpa0xDMQKnLHXsjKvo1ij3HUbxDvhVRBuu+1fE8VtNU0yLEWgOziur6l6P9BI1oFA16s8JEGN/XULIAPiA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/api-fetch": "^7.25.0", - "@wordpress/block-editor": "^14.20.0", - "@wordpress/blocks": "^14.14.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/html-entities": "^4.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/rich-text": "^7.25.0", - "@wordpress/sync": "^1.25.0", - "@wordpress/undo-manager": "^1.25.0", - "@wordpress/url": "^4.25.0", - "@wordpress/warning": "^3.25.0", + "@wordpress/api-fetch": "^7.27.0", + "@wordpress/block-editor": "^15.0.0", + "@wordpress/blocks": "^15.0.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/sync": "^1.27.0", + "@wordpress/undo-manager": "^1.27.0", + "@wordpress/url": "^4.27.0", + "@wordpress/warning": "^3.27.0", "change-case": "^4.1.2", "equivalent-key-map": "^0.2.2", "fast-deep-equal": "^3.1.3", @@ -7391,19 +8151,252 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/core-data/node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/block-editor": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-15.0.0.tgz", + "integrity": "sha512-hOJc0aNmx9i/Ndm2f1VTJ6D7txirLOiOPa21dmN6dKJEbtXkVp1POjtor1XwBv3Ups8K8Mo2NxtwIcc7LNcQtQ==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.27.0", + "@wordpress/api-fetch": "^7.27.0", + "@wordpress/blob": "^4.27.0", + "@wordpress/block-serialization-default-parser": "^5.27.0", + "@wordpress/blocks": "^15.0.0", + "@wordpress/commands": "^1.27.0", + "@wordpress/components": "^30.0.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/date": "^5.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/escape-html": "^3.27.0", + "@wordpress/hooks": "^4.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/keyboard-shortcuts": "^5.27.0", + "@wordpress/keycodes": "^4.27.0", + "@wordpress/notices": "^5.27.0", + "@wordpress/preferences": "^4.27.0", + "@wordpress/priority-queue": "^3.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/style-engine": "^2.27.0", + "@wordpress/token-list": "^3.27.0", + "@wordpress/upload-media": "^0.12.0", + "@wordpress/url": "^4.27.0", + "@wordpress/warning": "^3.27.0", + "@wordpress/wordcount": "^4.27.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "parsel-js": "^1.1.2", + "postcss": "^8.4.21", + "postcss-prefix-selector": "^1.16.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/blocks": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-15.0.0.tgz", + "integrity": "sha512-Gx1v2TfZ6RIejR4TQiqsG824HENE3sIxvTNuVtK68HDje4fdM8rAXRwA2IIMbKJ441xH4Yh8rlU7mmROWiyXBA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/autop": "^4.27.0", + "@wordpress/blob": "^4.27.0", + "@wordpress/block-serialization-default-parser": "^5.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/hooks": "^4.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/shortcode": "^4.27.0", + "@wordpress/warning": "^3.27.0", + "change-case": "^4.1.2", + "colord": "^2.7.0", + "fast-deep-equal": "^3.1.3", + "hpq": "^1.3.0", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "react-is": "^18.3.0", + "remove-accents": "^0.5.0", + "showdown": "^1.9.1", + "simple-html-tokenizer": "^0.5.7", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/components": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-30.0.0.tgz", + "integrity": "sha512-+9A36VLY6jz6TYmfDHzOWCYVz/wJQFBWZwfZmET8ce9yUKjeIQ+Zhhihj/EbTmmqSvZIgEgqinXTnnqCJr1OTA==", + "dependencies": { + "@ariakit/react": "^0.4.15", + "@babel/runtime": "7.25.7", + "@emotion/cache": "^11.7.1", + "@emotion/css": "^11.7.1", + "@emotion/react": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/styled": "^11.6.0", + "@emotion/utils": "^1.0.0", + "@floating-ui/react-dom": "2.0.8", + "@types/gradient-parser": "0.1.3", + "@types/highlight-words-core": "1.2.1", + "@use-gesture/react": "^10.3.1", + "@wordpress/a11y": "^4.27.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/date": "^5.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/escape-html": "^3.27.0", + "@wordpress/hooks": "^4.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/keycodes": "^4.27.0", + "@wordpress/primitives": "^4.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/warning": "^3.27.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.1.9", + "gradient-parser": "1.0.2", + "highlight-words-core": "^1.2.2", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "path-to-regexp": "^6.2.1", + "re-resizable": "^6.4.0", + "react-colorful": "^5.3.1", + "react-day-picker": "^9.7.0", + "remove-accents": "^0.5.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/upload-media": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@wordpress/upload-media/-/upload-media-0.12.0.tgz", + "integrity": "sha512-oKRzFuJhFdV2iOtmDhtmjxzmHjNKJ73StEV47Y7GZVAk5wWSjuqx5gdbBIbC3ECKPTRYNSBueloltl1h69PXHA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@wordpress/api-fetch": "^7.27.0", + "@wordpress/blob": "^4.27.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/preferences": "^4.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/url": "^4.27.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/@wordpress/data": { - "version": "10.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.25.0.tgz", - "integrity": "sha512-PHfF7S2jhgcH9D3Z9nskaQEDIbh0k0MX6KprzK4plT4Xu71YboMVWnBx78glzMMu17DOFoHJC25d+ymfGBM5rw==", + "version": "10.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.27.0.tgz", + "integrity": "sha512-+7S4GgAEBi87qNPN/Jl3sr3xuBnjHIaA7Vzfn3UqoCQ469JkyB65kbgfJOOGDz94sMhYZ4OoeQT3lpGsPBxnVA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/compose": "^7.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/is-shallow-equal": "^5.25.0", - "@wordpress/priority-queue": "^3.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/redux-routine": "^5.25.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/priority-queue": "^3.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/redux-routine": "^5.27.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -7432,12 +8425,12 @@ } }, "node_modules/@wordpress/date": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.25.0.tgz", - "integrity": "sha512-w3De486/qx2/MbxCCjiW7KS8lGhJ00VvnrbXRlrY9l/6yqbz0iMVglmFKrlLPftgutyhe3OSOSZsXX/uCF6yOg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.27.0.tgz", + "integrity": "sha512-DZ5OJlU8OliLpDaGi0KHhlphCujbppzAfb3y34CpWydSnSRSfVgzjzc2R4p17RIa9Vj9C6Q8FsnNBAiywaz39g==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/deprecated": "^4.25.0", + "@wordpress/deprecated": "^4.27.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -7458,9 +8451,9 @@ } }, "node_modules/@wordpress/dependency-extraction-webpack-plugin": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-6.25.0.tgz", - "integrity": "sha512-bAVve8ksBNfCcBq09IoTLCdF604UXtVh4Fb+/LBqyJc1kTTS02PsIv5aguSvCjcNSakQgvs7IJqEGJ2ZmP4JZg==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/dependency-extraction-webpack-plugin/-/dependency-extraction-webpack-plugin-6.27.0.tgz", + "integrity": "sha512-bCj39UT+jIJOm8lCQEXjz4SdADl1jVfccWs3nlZHbW5fxc+1Mh+lApnXKgmge9Ap+cuxvg9ewg+Hr3k8HC6dQg==", "dev": true, "dependencies": { "json2php": "^0.0.7" @@ -7480,12 +8473,12 @@ "dev": true }, "node_modules/@wordpress/deprecated": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.25.0.tgz", - "integrity": "sha512-NfVGSVfAESrgQRQu5QpyprTsDY0BLq6hJ2KrWlpscLetApxU5kSpP/wRzmjbtuuWSr5RsoopaeoTbiZNXb0QEA==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.27.0.tgz", + "integrity": "sha512-1rJTK7iy0oSE6eFUCBqCGG/wYuF62WoNDLF1G1Do+TdFGB4WxckHwTr5TuwtIG4CdoMjsPYIh2EnI3ziFOsHkA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/hooks": "^4.25.0" + "@wordpress/hooks": "^4.27.0" }, "engines": { "node": ">=18.12.0", @@ -7504,12 +8497,12 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.25.0.tgz", - "integrity": "sha512-uyP8oTjSYjU+OXSvpPITqMaF9Dk50WH7fiQIVUcjC/9VmrzIiaYaZ4USmuoUBtbFjJsSyANHw/anYMFqby9iIA==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.27.0.tgz", + "integrity": "sha512-uXcJslbSpxXX7EyMF4wtj+cydDyalapvu8HQ4QZleAAwJavhdNT+xpr/ai0XeApcxgIGHq1W05sYVN38lwVioQ==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/deprecated": "^4.25.0" + "@wordpress/deprecated": "^4.27.0" }, "engines": { "node": ">=18.12.0", @@ -7517,9 +8510,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.25.0.tgz", - "integrity": "sha512-HvGxncRhskqrkwyIPVsfznToFtSr6X0zBrIMHK7bgwGGiMr+yz5jYX3wnY1AsUDSr95ezhbCTdE2rNmvFkCD0g==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.27.0.tgz", + "integrity": "sha512-L1hZ1g1mMyt06tuMWt72uAJjlkjGOpR2Vxbo72ZZgO28PqQc1WLrvWN/W3LVViar9OQrR0yn/REYRd258iaNQw==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7551,9 +8544,9 @@ } }, "node_modules/@wordpress/e2e-test-utils-playwright": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-1.25.0.tgz", - "integrity": "sha512-M1jn4qH9iq1igLZ+sMQYNWp0P1tDgDsXF1iWWdqRn9wWcwHFn7iyDEEZ68uXzNvavkGyIHxZIoBcmKGeUA11/A==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-1.27.0.tgz", + "integrity": "sha512-UYjpPeI6vMZKWuZxegUoYu1zU+KumhUTm4EgRbo2TVxwkxeMrOX6XX7DP+NzaPj/DjkfVzfeRz9Ygby7lr6/LA==", "dev": true, "dependencies": { "change-case": "^4.1.2", @@ -7572,14 +8565,14 @@ } }, "node_modules/@wordpress/element": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.25.0.tgz", - "integrity": "sha512-zxdaf2s/en5Y+DfiswRZtQ+P8SvQ18+l5I2WmHb66+bVkFg7jrN+AJqLk86k2zcalOEjx7Fg4cce1wWytp8Wsw==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.27.0.tgz", + "integrity": "sha512-gHk4B0J0f7bEsDoUBdTm22vPQwmEWLZxyaojgRyx1ncE2IyktfmubD/q2NIcMEKh7p+Jq3ZUwzPcpchpvkH2mA==", "dependencies": { "@babel/runtime": "7.25.7", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.25.0", + "@wordpress/escape-html": "^3.27.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -7602,9 +8595,9 @@ } }, "node_modules/@wordpress/env": { - "version": "10.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-10.25.0.tgz", - "integrity": "sha512-jxChEEFmRhPbmn4KjHkdm5VE0NGZYiZ9U5T+QUkL1TTBc4AYPLTeOVQ0+hseIJUKY7dEjv26pJasKv6i2J/g4Q==", + "version": "10.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-10.27.0.tgz", + "integrity": "sha512-NEcfhdiTvc1TKyqzLFq94RAuB6XsyLCcj+YB1CaliIxaZ6mw3SEGM49/Z4JpgQKalqTjEYXgmAG/OQ+lLq0EgA==", "dev": true, "dependencies": { "@inquirer/prompts": "^7.2.0", @@ -7629,9 +8622,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.25.0.tgz", - "integrity": "sha512-sQ3graObu5K/RWrngk9bsULJ+9E7QLC6gMG34ja0Jm1LdeRjVgHv3FqP/uIkL36EvxEkjQ0LSbgbZsdV/E1q0w==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.27.0.tgz", + "integrity": "sha512-1LBB/xOFBUySSmVpd2nFwIZ8fVnP8dLNFl0wLprHVLtW6ZcdykO2ITY9bkaHu2lZ9HLRgHL7A/3R7MsJ1azYkg==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7687,56 +8680,29 @@ }, "peerDependenciesMeta": { "prettier": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, - "node_modules/@wordpress/eslint-plugin/node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/@wordpress/eslint-plugin/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optional": true + }, + "typescript": { + "optional": true + } } }, - "node_modules/@wordpress/eslint-plugin/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@wordpress/eslint-plugin/node_modules/eslint-config-prettier": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz", + "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", "dev": true, - "engines": { - "node": ">=10" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "eslint": ">=7.0.0" } }, "node_modules/@wordpress/hooks": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.25.0.tgz", - "integrity": "sha512-IWqgozRE+8PE96TIsf5bfS7ezZfvleSm1YZAuhAWYH7QUVm07WK7/yhhDYkj9QyTpWSZnGkmR7YYH/NJ8jaMDQ==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.27.0.tgz", + "integrity": "sha512-sGaNVZKMxwnhGSge0tZZsGfImLPimiulUkM7hivQ2CSCgibTpgxFRBJ1r7gbNLDF+qHQK9a26K8fGfKnAal6Cg==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7757,9 +8723,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.25.0.tgz", - "integrity": "sha512-SEf8nnLm85KH2fZiEzUgLuh4Nd53iW0rmA5k9xM7n0uM6BA6HMDidtT/5wxTlnMH8cxOSjL2IkCHwhuRFTibbg==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.27.0.tgz", + "integrity": "sha512-4MfLS3k6+dlPSPbccnCloIFdbWjT6x0sRLNcVNWAI7I+nov7A34/cI/xjXFPcQaeewBE+24Q2TWsyFhcX2r89Q==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7780,12 +8746,12 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.25.0.tgz", - "integrity": "sha512-6MWkwmA9dwiLA+N4cj81JxxSqgJ+5HeLZHa3Sy2u7A2f4wgGCH+Bj2T6eQnZdky9fMy4vjvUpUZdv5sdmtYJlQ==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.26.0.tgz", + "integrity": "sha512-YHzaUWlCuN2ynl47qbsdMkTGtP52+E1giDOdWBgUaSexUYjbeFxKFUzRMB0Wuh1psL80+VzvJOH/mU440KAJnA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/hooks": "^4.25.0", + "@wordpress/hooks": "^4.26.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -7811,13 +8777,13 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.25.0.tgz", - "integrity": "sha512-CNAgZ0ZE6pPjLWxPLBdmIQlxpkQCNZ9Zv4wuUDSMqG0jJDdf+YCpklwIMLWbv9WVubmzgURo54qeCedbpXhCjA==", + "version": "10.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.27.0.tgz", + "integrity": "sha512-KeOz3aLtd7p+cA287gmGzpC9kIO1lxPBn/lDPkXfc8oz482XqNJKohdW/7ZMlEWx1uEcZUI+g3vfSA+gKDgjUQ==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/element": "^6.25.0", - "@wordpress/primitives": "^4.25.0" + "@wordpress/element": "^6.27.0", + "@wordpress/primitives": "^4.27.0" }, "engines": { "node": ">=18.12.0", @@ -7836,9 +8802,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.25.0.tgz", - "integrity": "sha512-/37IIoJz8/mp7TGZbdmakXr6YKqvpjYUHJx9LA9ibVVh6AsM72nI7N5V3AsGndan46vItfzhs0zpEWI7xF86Gw==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.27.0.tgz", + "integrity": "sha512-sYlAuNgEwQHioKSx3jyV6ZJlBR19sEvIdkBVoGF82OAxbXFzRvoD6V4zy+kZzY6V99FE12L93I0t5jh4qOn2lg==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -7859,9 +8825,9 @@ } }, "node_modules/@wordpress/jest-console": { - "version": "8.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-8.25.0.tgz", - "integrity": "sha512-X2YzKV1Pv5PC6QHqUp+FDlBgu7C+a2Yxdk6p4XDsTIjLV+I7eQuAdBUMzjyKSd1wN/Tx0x6Dr7/HmrV0ThRm1Q==", + "version": "8.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-8.27.0.tgz", + "integrity": "sha512-MTKc5oWkmzVqSP0SxH5XCxZEpFUgd+uBn2byEjtbSPqTi3n6uou+LybtRWHSKeCAHVBcq3Bsng1V14oJRyl7Pg==", "dev": true, "dependencies": { "@babel/runtime": "7.25.7", @@ -7888,12 +8854,12 @@ } }, "node_modules/@wordpress/jest-preset-default": { - "version": "12.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-12.25.0.tgz", - "integrity": "sha512-YLKfgQl5ZW63XuJh24Mzv1yXIO4otTXg9fTbSsEAHhZI8KQL9VuFJgNQ4hE8lZV2Wbmy6Njh8q4TY05/oMJ3KA==", + "version": "12.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-12.27.0.tgz", + "integrity": "sha512-J2sYHUB5fdmJ9IVnb5AJkFUMusVAQCZdFvphYSZZ+wq9qvyEp8SrTcIT1uj5zE/S/HdpkTQKRaJ56x0RZI9lFQ==", "dev": true, "dependencies": { - "@wordpress/jest-console": "^8.25.0", + "@wordpress/jest-console": "^8.27.0", "babel-jest": "29.7.0" }, "engines": { @@ -7906,14 +8872,14 @@ } }, "node_modules/@wordpress/keyboard-shortcuts": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.25.0.tgz", - "integrity": "sha512-g78ZZnoQMmQ70rVcvnxkIZ0VpOaZH34CxC9QSBASRfmoVrM9pFZFZJPDE/KoUt8qEFQqgTOVMpn0GenT2NEPXA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.27.0.tgz", + "integrity": "sha512-cXllgxPZP8JDcg2nC66FWk3cHBnmCo8iqZW6j078x/TCnixYE+p14Y60/Y9bdtJKhJ77TrGswuhZGvEHho1Nbw==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/data": "^10.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/keycodes": "^4.25.0" + "@wordpress/data": "^10.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/keycodes": "^4.27.0" }, "engines": { "node": ">=18.12.0", @@ -7935,12 +8901,12 @@ } }, "node_modules/@wordpress/keycodes": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.25.0.tgz", - "integrity": "sha512-cnV4/7RY4m+DNo3BF10pHdFITKyoYr4TqvcSmka5O7RulPQi/PTeLcFgTTM+LrULGSNfV5ZUgIuPwLpLA5pqGQ==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.27.0.tgz", + "integrity": "sha512-fWyEcLI2rAZn6FwVBITGFxo8aS7EQrt8icOdxS5Es3Ii8DneQUl2gtXs3tq9viX4cWCno7cEt+dpuuv2gPxwoQ==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/i18n": "^5.25.0" + "@wordpress/i18n": "^6.0.0" }, "engines": { "node": ">=18.12.0", @@ -7958,17 +8924,37 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/keycodes/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/media-utils": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-5.25.0.tgz", - "integrity": "sha512-2232bVB3T7IW0lDbPC2Tv2lA0yZJXv6S6H4QjpQE7UJnGPrTTcgPTrES9h39H47JTwrwja6FKSCUpREUbgNXzA==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-5.27.0.tgz", + "integrity": "sha512-E8Xvg/Kbgacopq+LRkcxVCxOPGqyg2sV+KLa567VA5rAaUnnD2g9gsTEiZAbmz97wypqii+5g4MypXC6rxn0Ew==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/api-fetch": "^7.25.0", - "@wordpress/blob": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/private-apis": "^1.25.0" + "@wordpress/api-fetch": "^7.27.0", + "@wordpress/blob": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/private-apis": "^1.27.0" }, "engines": { "node": ">=18.12.0", @@ -7986,14 +8972,34 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/media-utils/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/notices": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.25.0.tgz", - "integrity": "sha512-BvgvvFPa9eA98Xiyb0NeTqfuVfD+5TMfBmWId+y6iwbplKHetW/Bj/36qRWzUGptPh3ae7NKc/ovi4KDO4t9og==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.27.0.tgz", + "integrity": "sha512-WF//lHwg5gANVZctc8xRIOoHVHzn+En3Mj4y2cij/qlw3Xm24oaOSvBhEFKkn7oP092YAzG20zMNMaSngcbtGA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/a11y": "^4.25.0", - "@wordpress/data": "^10.25.0" + "@wordpress/a11y": "^4.27.0", + "@wordpress/data": "^10.27.0" }, "engines": { "node": ">=18.12.0", @@ -8015,9 +9021,9 @@ } }, "node_modules/@wordpress/npm-package-json-lint-config": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-5.25.0.tgz", - "integrity": "sha512-wB35qxGlVkBx0GdoxDXjySMACHYgfrFacYcP6IkYHMu1e7/HU/Kz8ZW2g+4A+nea/SPO46V6xuSbayrYy6c+UQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/npm-package-json-lint-config/-/npm-package-json-lint-config-5.27.0.tgz", + "integrity": "sha512-BEumv8etwMVgz1xvO1TOuSbOVB4dBwhtM6dSHchd4m5RPfmt/FpX+NWToSbF06+l+Ha6PVry72TiQpdFok9c8w==", "dev": true, "engines": { "node": ">=18.12.0", @@ -8028,12 +9034,12 @@ } }, "node_modules/@wordpress/postcss-plugins-preset": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-5.25.0.tgz", - "integrity": "sha512-J9RK9R1cwiOBXC/iORi1Kz1i9VEASAv7OnERGxtHtbXFsPXq1cHDNJ3slwYGovUPjMOvfDNMjCgTWtM3MizEag==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/postcss-plugins-preset/-/postcss-plugins-preset-5.27.0.tgz", + "integrity": "sha512-iIhl8fc4zeN1rehf/bvC2+oIFSTiFfnZf2aTDCzErQTgvGZ33cUlfx7CrpJPcVYCQcbvp4IdaYgaVaw/lnpmuQ==", "dev": true, "dependencies": { - "@wordpress/base-styles": "^6.1.0", + "@wordpress/base-styles": "^6.3.0", "autoprefixer": "^10.4.20" }, "engines": { @@ -8045,20 +9051,20 @@ } }, "node_modules/@wordpress/preferences": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.25.0.tgz", - "integrity": "sha512-zKBqF7mLiONH3LqYuruDGF6K9yWJj2fRSvgNVkcftQr7jPDys8c6F29+YQWDf1trs5MaYxhoenZQSenqf1oljQ==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.27.0.tgz", + "integrity": "sha512-+b8E0iTQD0KObihwYYrKdPsQa6ltGmMn2hLDXZqP3RPKfIDoleDvGK/zbwoKsKe+y4HN+qL7gQqKjsXuxdoeDA==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/a11y": "^4.25.0", - "@wordpress/components": "^29.11.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/icons": "^10.25.0", - "@wordpress/private-apis": "^1.25.0", + "@wordpress/a11y": "^4.27.0", + "@wordpress/components": "^30.0.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/private-apis": "^1.27.0", "clsx": "^2.1.1" }, "engines": { @@ -8081,6 +9087,99 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/preferences/node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@wordpress/preferences/node_modules/@wordpress/components": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-30.0.0.tgz", + "integrity": "sha512-+9A36VLY6jz6TYmfDHzOWCYVz/wJQFBWZwfZmET8ce9yUKjeIQ+Zhhihj/EbTmmqSvZIgEgqinXTnnqCJr1OTA==", + "dependencies": { + "@ariakit/react": "^0.4.15", + "@babel/runtime": "7.25.7", + "@emotion/cache": "^11.7.1", + "@emotion/css": "^11.7.1", + "@emotion/react": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/styled": "^11.6.0", + "@emotion/utils": "^1.0.0", + "@floating-ui/react-dom": "2.0.8", + "@types/gradient-parser": "0.1.3", + "@types/highlight-words-core": "1.2.1", + "@use-gesture/react": "^10.3.1", + "@wordpress/a11y": "^4.27.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/date": "^5.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/dom": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/escape-html": "^3.27.0", + "@wordpress/hooks": "^4.27.0", + "@wordpress/html-entities": "^4.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/icons": "^10.27.0", + "@wordpress/is-shallow-equal": "^5.27.0", + "@wordpress/keycodes": "^4.27.0", + "@wordpress/primitives": "^4.27.0", + "@wordpress/private-apis": "^1.27.0", + "@wordpress/rich-text": "^7.27.0", + "@wordpress/warning": "^3.27.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.1.9", + "gradient-parser": "1.0.2", + "highlight-words-core": "^1.2.2", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "path-to-regexp": "^6.2.1", + "re-resizable": "^6.4.0", + "react-colorful": "^5.3.1", + "react-day-picker": "^9.7.0", + "remove-accents": "^0.5.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/preferences/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/preferences/node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -8090,9 +9189,9 @@ } }, "node_modules/@wordpress/prettier-config": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-4.25.0.tgz", - "integrity": "sha512-P18anKvMO9lEpr2827No0SFmeypX1A5Ce3DZ4NdNNnoJRGYkdlwRzwMpMoB9XpAQz5o45ystBrak2/OqzdBWLg==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-4.27.0.tgz", + "integrity": "sha512-G9sNZ13tgoCwYxZ49jvWMROcRw4JuQjlcct275CAz5wc+blTyob8YPlWAyAJY1h1Q0Nr8cuclS+kdzwD8HCUkg==", "dev": true, "engines": { "node": ">=18.12.0", @@ -8103,12 +9202,12 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.25.0.tgz", - "integrity": "sha512-I8voo9KWDFOgVUzxO0n1UtaTGBwhA/MuYmh6Bpn4M33SQAm4K5aUFidnJOelILWSA4Ox4R7wskGhuItfyty1LA==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.27.0.tgz", + "integrity": "sha512-ZIhpB4ZmZwMSsrELx4mzhRvxAoqgk8sSE3PaRt/ue4GXFoRRQgI3RVCwEdiNPcsQXId9lOQIhAJNDt5Wa0Fbgg==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/element": "^6.25.0", + "@wordpress/element": "^6.27.0", "clsx": "^2.1.1" }, "engines": { @@ -8139,9 +9238,9 @@ } }, "node_modules/@wordpress/priority-queue": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.25.0.tgz", - "integrity": "sha512-HtN8G1o/TaUIhapJf6Kq2dy1OOpC1beGB7sJUvq5JrwKd3VRdrXx0K3HKoHe99EJoE9v6lgEIS5VtVIaW0u0cQ==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.27.0.tgz", + "integrity": "sha512-RpIaX59sji45x9oUYrkbTHbagJuHC05oZOjJDzLj2Qv12bGeq0QWI2+e59yl3wONLpVla7f3TfNsFapkgOhOAw==", "dependencies": { "@babel/runtime": "7.25.7", "requestidlecallback": "^0.3.0" @@ -8163,9 +9262,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.25.0.tgz", - "integrity": "sha512-O+Vo4h1CjKkYubduKVXW2fi7vvse7YyyvQOEdCut0Sl9uc0lVoHB0Wstc2sHllDTAI2fyjTLrLbddYuM7sVvMA==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.27.0.tgz", + "integrity": "sha512-u5EqKxkE4BHKOSlLPW+o632t2YnzJkZTjwnNFolswWI9+g5SiXRpM8Q7+1CNquqcgDcSNKId7S9UCE1fw1FhAw==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -8186,9 +9285,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.25.0.tgz", - "integrity": "sha512-0YZNyuL1QO3CbA6njHzoHMmYX+tnOSUIOpag5jeeNKzNE7iThKRmD07HtMo+hL5B3EFumvWDXlwOLpoi2xBJuw==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.27.0.tgz", + "integrity": "sha512-6eulRxrF40yKtGjzHKsY2pzD5/sbWaNjXRrFQZY+wMNsYV6AWYacgn3r+2r51Uhlut6zZl6x8YJtCcqGOHnKEQ==", "dependencies": { "@babel/runtime": "7.25.7", "is-plain-object": "^5.0.0", @@ -8215,19 +9314,19 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.25.0.tgz", - "integrity": "sha512-7M7kD5ix4XjuNRZP4ijG9jGhK+alMVO9nB2jCHIZW8RoGpnZ5QdITGQ25OOYhcIcBhRcAxP+1JS0yn2qzqkBOw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.27.0.tgz", + "integrity": "sha512-khZm3EqCcI0abZZhNWn9EhwFbLEyCy8X4+7IcJNzyKSZiDsP7HS1ch7Zo3lVPJAMWFeeqwDQJ3zSZwCL24Eg8w==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/a11y": "^4.25.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/deprecated": "^4.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/escape-html": "^3.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/keycodes": "^4.25.0", + "@wordpress/a11y": "^4.27.0", + "@wordpress/compose": "^7.27.0", + "@wordpress/data": "^10.27.0", + "@wordpress/deprecated": "^4.27.0", + "@wordpress/element": "^6.27.0", + "@wordpress/escape-html": "^3.27.0", + "@wordpress/i18n": "^6.0.0", + "@wordpress/keycodes": "^4.27.0", "memize": "^2.1.0" }, "engines": { @@ -8249,25 +9348,45 @@ "node": ">=6.9.0" } }, + "node_modules/@wordpress/rich-text/node_modules/@wordpress/i18n": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-6.0.0.tgz", + "integrity": "sha512-ItvO/E3v39VX+5nZacyzwulhzRukiB2+1zqndWgOSNnERYnK/0hLHIWWthRFxYEPF13H54orXg68n17MZQ8whA==", + "dependencies": { + "@babel/runtime": "7.25.7", + "@tannin/sprintf": "^1.3.1", + "@wordpress/hooks": "^4.27.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/scripts": { - "version": "30.18.0", - "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-30.18.0.tgz", - "integrity": "sha512-NVtJYcmWjq57TDc0kStw0oeejpejH2KSJklOrDKf4Sah4gDQqy695COnHSVVoujCgUm6a5uv5+3mpujF08JsRA==", + "version": "30.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-30.20.0.tgz", + "integrity": "sha512-LV3WG1UR7QeE4zE6nkWi6r3bmPn+MyjWOA0Ycpy23kOoabeurSob/hurfPUjzg4/i4wipJZ9MQyV4uWSEGHt4w==", "dev": true, "dependencies": { "@babel/core": "7.25.7", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@svgr/webpack": "^8.0.1", - "@wordpress/babel-preset-default": "^8.25.0", - "@wordpress/browserslist-config": "^6.25.0", - "@wordpress/dependency-extraction-webpack-plugin": "^6.25.0", - "@wordpress/e2e-test-utils-playwright": "^1.25.0", - "@wordpress/eslint-plugin": "^22.11.0", - "@wordpress/jest-preset-default": "^12.25.0", - "@wordpress/npm-package-json-lint-config": "^5.25.0", - "@wordpress/postcss-plugins-preset": "^5.25.0", - "@wordpress/prettier-config": "^4.25.0", - "@wordpress/stylelint-config": "^23.17.0", + "@wordpress/babel-preset-default": "^8.27.0", + "@wordpress/browserslist-config": "^6.27.0", + "@wordpress/dependency-extraction-webpack-plugin": "^6.27.0", + "@wordpress/e2e-test-utils-playwright": "^1.27.0", + "@wordpress/eslint-plugin": "^22.13.0", + "@wordpress/jest-preset-default": "^12.27.0", + "@wordpress/npm-package-json-lint-config": "^5.27.0", + "@wordpress/postcss-plugins-preset": "^5.27.0", + "@wordpress/prettier-config": "^4.27.0", + "@wordpress/stylelint-config": "^23.19.0", "adm-zip": "^0.5.9", "babel-jest": "29.7.0", "babel-loader": "9.2.1", @@ -8360,16 +9479,16 @@ } }, "node_modules/@wordpress/scripts/node_modules/@wordpress/eslint-plugin": { - "version": "22.11.0", - "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-22.11.0.tgz", - "integrity": "sha512-JxN4T7r0k9lePG1dDJ2bxyqc5zFtLeTY0Ns8EfU2G/QZsB6gvxGTLhK2u6csflswUt2vnJ3oCT5MbPfANJuLDg==", + "version": "22.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-22.13.0.tgz", + "integrity": "sha512-cD7NpkCwH3bPhNcS16P0SEvlXrlx5XN5yCT7CZo3DReRTFlOMKswIg/csqFgvypIW8L2Qla5Rzva1qVsWnQEvg==", "dev": true, "dependencies": { "@babel/eslint-parser": "7.25.7", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", - "@wordpress/babel-preset-default": "^8.25.0", - "@wordpress/prettier-config": "^4.25.0", + "@wordpress/babel-preset-default": "^8.27.0", + "@wordpress/prettier-config": "^4.27.0", "cosmiconfig": "^7.0.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.2", @@ -8403,9 +9522,9 @@ } }, "node_modules/@wordpress/scripts/node_modules/@wordpress/eslint-plugin/node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz", + "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -8414,21 +9533,6 @@ "eslint": ">=7.0.0" } }, - "node_modules/@wordpress/scripts/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wordpress/scripts/node_modules/prettier": { "name": "wp-prettier", "version": "3.0.3", @@ -8445,22 +9549,10 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@wordpress/scripts/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@wordpress/shortcode": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.25.0.tgz", - "integrity": "sha512-KF217XFpIz40yOGyaH4jlM4O82Bkkj+D60/HLByGY5Q5ObB7NSeCuhrp7YDBlXKXE682r4Lep8+MfwaJ/MRLYw==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.27.0.tgz", + "integrity": "sha512-7UyI2Exqt789MrWO4LQWtvfdBisAVDUfHgTj8Rqq3QJ6dE5zlxM1UJwaxIQArFv39gS1hOibfNUxigKFQ+IW9A==", "dependencies": { "@babel/runtime": "7.25.7", "memize": "^2.0.1" @@ -8482,9 +9574,9 @@ } }, "node_modules/@wordpress/style-engine": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.25.0.tgz", - "integrity": "sha512-myjrI1+7WIEjfto+APXVkiuGUpidM4d6dVjs/JhN58Yn5O3j+3o9N7Y+YAzBHcq9HofuH3zJDuo+mOppDyUriw==", + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.27.0.tgz", + "integrity": "sha512-boTPFzKuVxEiXpaKu7qFIa5MyPVp5f5BHCiEqcsppcjGOtwdhLv1sSHGJdtUzsbe43yZ0pyY7q8a5dCmk5rjIw==", "dependencies": { "@babel/runtime": "7.25.7", "change-case": "^4.1.2" @@ -8506,9 +9598,9 @@ } }, "node_modules/@wordpress/stylelint-config": { - "version": "23.17.0", - "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-23.17.0.tgz", - "integrity": "sha512-FYA2pEJWLfC3g08rmBmEY6frRD45NLBpLX1W4tLgPDFwC21WHr9aEvIdPS4YF+1/kNwRGWdkTITcR2Lq5dZ4wg==", + "version": "23.19.0", + "resolved": "https://registry.npmjs.org/@wordpress/stylelint-config/-/stylelint-config-23.19.0.tgz", + "integrity": "sha512-qriyn7AVc+h18yCh7oK/XY776THnENL7kuZi9IEM08k2dVmBt4hOeJlEKqumkBCBqtA/+JFPT38GlJpaV1+cHg==", "dev": true, "dependencies": { "@stylistic/stylelint-plugin": "^3.0.1", @@ -8525,13 +9617,13 @@ } }, "node_modules/@wordpress/sync": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.25.0.tgz", - "integrity": "sha512-VQUihV36ITmgHovTYOgbuv7R+QCJ0AG1tG6/dxiqdPwbSEj78LFcA6Nr8MdUqZAOiAIFG3D8bE61UbxiGuud8g==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.27.0.tgz", + "integrity": "sha512-HrlVEmV9aR1Y6JtJ2iWELeWQ8dJcDlc/YSpEl4VPPSeh1z+++VL9ISZqBE73qxbXbIkLGpfnCevL28jaPwppMQ==", "dependencies": { "@babel/runtime": "7.25.7", "@types/simple-peer": "^9.11.5", - "@wordpress/url": "^4.25.0", + "@wordpress/url": "^4.27.0", "import-locals": "^2.0.0", "lib0": "^0.2.42", "simple-peer": "^9.11.0", @@ -8557,9 +9649,9 @@ } }, "node_modules/@wordpress/token-list": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.25.0.tgz", - "integrity": "sha512-K3Edpzo6/jxcF4q8xa9vMJsgpTSNDUyrW0jFR7qPoJOng+ypS0uBwQHJjGS9eEgDrx/CNd06C5TRaWHPwUrgYg==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.27.0.tgz", + "integrity": "sha512-yUjWvRTtI/7wwTzEk1UZV98c2XN2LZ4/IepJdBHzhBznrE294gX/A6y7mrL1la5TKQeUPN4TSvh11dpQMMpZAQ==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -8580,12 +9672,12 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.25.0.tgz", - "integrity": "sha512-Y+f8Xa+vpG+Cj/ekeI6ky54p/UTlFUZmutBusmsH+QzaGHb9bVKHPhXfTLyjhdDIUE3YV0vqz32DjNrbuiGRWg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.27.0.tgz", + "integrity": "sha512-ndGz3mW0fu7YM7vTuNKqxXBPrpWvrefScD8dmdqeIVs+yDZo8PNpEvrTVfb7FM/gujD6Dh95OSuW5TNpNN6EIw==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/is-shallow-equal": "^5.25.0" + "@wordpress/is-shallow-equal": "^5.27.0" }, "engines": { "node": ">=18.12.0", @@ -8604,20 +9696,20 @@ } }, "node_modules/@wordpress/upload-media": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@wordpress/upload-media/-/upload-media-0.10.0.tgz", - "integrity": "sha512-FqhUvGCUmM1E9d+ggtxNAXtB3G/NqWIW6Ib47oFI+7avb0m0N/XjkrLZgRZOIVWILd3YLpWF6lPTgVHLhJ28qw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@wordpress/upload-media/-/upload-media-0.11.0.tgz", + "integrity": "sha512-bzgwuupDWhx6mU93ShYTmFCTD2rhjHeHAJB5p/slx/sfEA13BxAYG7ZCKSKDNWrwxbA4i669BnhjW3h7PsGklg==", "dependencies": { "@babel/runtime": "7.25.7", - "@wordpress/api-fetch": "^7.25.0", - "@wordpress/blob": "^4.25.0", - "@wordpress/compose": "^7.25.0", - "@wordpress/data": "^10.25.0", - "@wordpress/element": "^6.25.0", - "@wordpress/i18n": "^5.25.0", - "@wordpress/preferences": "^4.25.0", - "@wordpress/private-apis": "^1.25.0", - "@wordpress/url": "^4.25.0", + "@wordpress/api-fetch": "^7.26.0", + "@wordpress/blob": "^4.26.0", + "@wordpress/compose": "^7.26.0", + "@wordpress/data": "^10.26.0", + "@wordpress/element": "^6.26.0", + "@wordpress/i18n": "^5.26.0", + "@wordpress/preferences": "^4.26.0", + "@wordpress/private-apis": "^1.26.0", + "@wordpress/url": "^4.26.0", "uuid": "^9.0.1" }, "engines": { @@ -8641,9 +9733,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.25.0.tgz", - "integrity": "sha512-IQE/Ck4lEu65VhYcCoMedusIurc+oZtxWUZkn/SoMBJm2ft5zw8oHzHkyDdU/DcrYVKoqV+dAPRPZMHyVrGUTQ==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.27.0.tgz", + "integrity": "sha512-7+WJ2g5xvfRjsnLRixXDVZzEg7jQUYRNPOBbjO95D9kJ3Sm63Lu4xc3FOikeojOUJv5/Z9c2zKOsaotNkWHexg==", "dependencies": { "@babel/runtime": "7.25.7", "remove-accents": "^0.5.0" @@ -8665,18 +9757,18 @@ } }, "node_modules/@wordpress/warning": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.25.0.tgz", - "integrity": "sha512-Pp4+1zgY6wDqiGPpb33+B7YplujkFyMVmi2VDBbJcy/OEXNU/cowfjYuGxgyQpJlCpKnrmVYV+snowZ3Iytk0g==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.27.0.tgz", + "integrity": "sha512-AGcCLU2urtV7C4i4Oji8tL9froFPDie+99A2N3tqjZU1v7Csw4UgDrptYRyENjhXLBe9ZzVlf1mZmgH/MQPAHA==", "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" } }, "node_modules/@wordpress/wordcount": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.25.0.tgz", - "integrity": "sha512-5e5LjZGMOVDiRxT9rOZW2VnUyM6MuWFJTp31W6CeaP4p+1qeie7Gg5lyZXgePIk47HlRtfpjsv0KzuepDl+YhQ==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.27.0.tgz", + "integrity": "sha512-XIDqA9YnYC5yH6Lyk25m+q8wYH2sp+2p5ROrOp2gQ0Due+wUycAIgvzJsbnQoMn0PZrqgaETxFymtkQhGWj6Ug==", "dependencies": { "@babel/runtime": "7.25.7" }, @@ -8764,6 +9856,27 @@ "acorn-walk": "^8.0.2" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -9244,6 +10357,16 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/atomically": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-2.0.3.tgz", + "integrity": "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==", + "dev": true, + "dependencies": { + "stubborn-fs": "^1.2.5", + "when-exit": "^2.1.1" + } + }, "node_modules/autoprefixer": { "version": "10.4.21", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", @@ -9311,13 +10434,13 @@ } }, "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "dev": true, "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -9420,13 +10543,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", - "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.4", + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { @@ -9447,12 +10570,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", - "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.4" + "@babel/helper-define-polyfill-provider": "^0.6.5" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -9507,16 +10630,16 @@ "dev": true }, "node_modules/bare-events": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", - "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.6.0.tgz", + "integrity": "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg==", "dev": true, "optional": true }, "node_modules/bare-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz", - "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.6.tgz", + "integrity": "sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ==", "dev": true, "optional": true, "dependencies": { @@ -9718,9 +10841,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "dev": true, "funding": [ { @@ -9737,8 +10860,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, @@ -9818,13 +10941,13 @@ } }, "node_modules/cacheable": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.0.tgz", - "integrity": "sha512-SSgQTAnhd7WlJXnGlIi4jJJOiHzgnM5wRMEPaXAU4kECTAMpBoYKoZ9i5zHmclIEZbxcu3j7yY/CF8DTmwIsHg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.2.tgz", + "integrity": "sha512-hMkETCRV4hwBAvjQY1/xGw15tlPj+7cM4d5HOlYJJFftLQVRCboVX+mT6AJ6eL0fsqUhSUwDiF+pgfTR2r2Hxg==", "dev": true, "dependencies": { - "hookified": "^1.8.2", - "keyv": "^5.3.3" + "hookified": "^1.10.0", + "keyv": "^5.3.4" } }, "node_modules/cacheable-lookup": { @@ -9855,12 +10978,12 @@ } }, "node_modules/cacheable/node_modules/keyv": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz", - "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.4.0.tgz", + "integrity": "sha512-TMckyVjEoacG5IteUpUrOBsFORtheqziVyyY2dLUwg1jwTb8u48LX4TgmtogkNl9Y9unaEJ1luj10fGyjMGFOQ==", "dev": true, "dependencies": { - "@keyv/serialize": "^1.0.3" + "@keyv/serialize": "^1.1.0" } }, "node_modules/call-bind": { @@ -9987,9 +11110,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001723", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", - "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "dev": true, "funding": [ { @@ -10455,16 +11578,16 @@ } }, "node_modules/compression": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", - "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "dev": true, "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", - "on-headers": "~1.0.2", + "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" }, @@ -10514,53 +11637,21 @@ } }, "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/configstore/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-7.0.0.tgz", + "integrity": "sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "atomically": "^2.0.3", + "dot-prop": "^9.0.0", + "graceful-fs": "^4.2.11", + "xdg-basedir": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/configstore/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/configstore/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "url": "https://github.com/yeoman/configstore?sponsor=1" } }, "node_modules/connect-history-api-fallback": { @@ -10699,9 +11790,9 @@ } }, "node_modules/core-js": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", - "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.44.0.tgz", + "integrity": "sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==", "dev": true, "hasInstallScript": true, "funding": { @@ -10710,12 +11801,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz", - "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", + "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", "dev": true, "dependencies": { - "browserslist": "^4.25.0" + "browserslist": "^4.25.1" }, "funding": { "type": "opencollective", @@ -10723,9 +11814,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.43.0.tgz", - "integrity": "sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.44.0.tgz", + "integrity": "sha512-gvMQAGB4dfVUxpYD0k3Fq8J+n5bB6Ytl15lqlZrOIXFzxOhtPaObfkQGHtMRdyjIf7z2IeNULwi1jEwyS+ltKQ==", "dev": true, "hasInstallScript": true, "funding": { @@ -10789,15 +11880,6 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/csp_evaluator": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/csp_evaluator/-/csp_evaluator-1.1.5.tgz", @@ -10916,13 +11998,22 @@ } } }, + "node_modules/css-minimizer-webpack-plugin/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.7.tgz", - "integrity": "sha512-evKu7yiDIF7oS+EIpwFlMF730ijRyLFaM2o5cTxRGJR9OKHKkc+qP443ZEVR9kZG0syaAJJCPJyfv5pbrxlSng==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.0.tgz", + "integrity": "sha512-Pu3rlKkd0ZtlCUzBrKL1Z4YmhKppjC1H9jo7u1o4qaKqyhvixFgu5qLyNIAOjSTg9DjVPtUqdROq2EfpVMEe+w==", "dev": true, "dependencies": { - "cssnano-preset-default": "^7.0.7", + "cssnano-preset-default": "^7.0.8", "lilconfig": "^3.1.3" }, "engines": { @@ -10937,26 +12028,26 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano-preset-default": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.7.tgz", - "integrity": "sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==", + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.8.tgz", + "integrity": "sha512-d+3R2qwrUV3g4LEMOjnndognKirBZISylDZAF/TPeCWVjEwlXS2e4eN4ICkoobRe7pD3H6lltinKVyS1AJhdjQ==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "css-declaration-sorter": "^7.2.0", "cssnano-utils": "^5.0.1", "postcss-calc": "^10.1.1", - "postcss-colormin": "^7.0.3", - "postcss-convert-values": "^7.0.5", + "postcss-colormin": "^7.0.4", + "postcss-convert-values": "^7.0.6", "postcss-discard-comments": "^7.0.4", "postcss-discard-duplicates": "^7.0.2", "postcss-discard-empty": "^7.0.1", "postcss-discard-overridden": "^7.0.1", "postcss-merge-longhand": "^7.0.5", - "postcss-merge-rules": "^7.0.5", + "postcss-merge-rules": "^7.0.6", "postcss-minify-font-values": "^7.0.1", "postcss-minify-gradients": "^7.0.1", - "postcss-minify-params": "^7.0.3", + "postcss-minify-params": "^7.0.4", "postcss-minify-selectors": "^7.0.5", "postcss-normalize-charset": "^7.0.1", "postcss-normalize-display-values": "^7.0.1", @@ -10964,13 +12055,13 @@ "postcss-normalize-repeat-style": "^7.0.1", "postcss-normalize-string": "^7.0.1", "postcss-normalize-timing-functions": "^7.0.1", - "postcss-normalize-unicode": "^7.0.3", + "postcss-normalize-unicode": "^7.0.4", "postcss-normalize-url": "^7.0.1", "postcss-normalize-whitespace": "^7.0.1", "postcss-ordered-values": "^7.0.2", - "postcss-reduce-initial": "^7.0.3", + "postcss-reduce-initial": "^7.0.4", "postcss-reduce-transforms": "^7.0.1", - "postcss-svgo": "^7.0.2", + "postcss-svgo": "^7.1.0", "postcss-unique-selectors": "^7.0.4" }, "engines": { @@ -11009,12 +12100,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-colormin": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.3.tgz", - "integrity": "sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.4.tgz", + "integrity": "sha512-ziQuVzQZBROpKpfeDwmrG+Vvlr0YWmY/ZAk99XD+mGEBuEojoFekL41NCsdhyNUtZI7DPOoIWIR7vQQK9xwluw==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "caniuse-api": "^3.0.0", "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" @@ -11027,12 +12118,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-convert-values": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.5.tgz", - "integrity": "sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.6.tgz", + "integrity": "sha512-MD/eb39Mr60hvgrqpXsgbiqluawYg/8K4nKsqRsuDX9f+xN1j6awZCUv/5tLH8ak3vYp/EMXwdcnXvfZYiejCQ==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -11110,12 +12201,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-merge-rules": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.5.tgz", - "integrity": "sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.6.tgz", + "integrity": "sha512-2jIPT4Tzs8K87tvgCpSukRQ2jjd+hH6Bb8rEEOUDmmhOeTcqDg5fEFK8uKIu+Pvc3//sm3Uu6FRqfyv7YF7+BQ==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "caniuse-api": "^3.0.0", "cssnano-utils": "^5.0.1", "postcss-selector-parser": "^7.1.0" @@ -11160,12 +12251,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-params": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.3.tgz", - "integrity": "sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.4.tgz", + "integrity": "sha512-3OqqUddfH8c2e7M35W6zIwv7jssM/3miF9cbCSb1iJiWvtguQjlxZGIHK9JRmc8XAKmE2PFGtHSM7g/VcW97sw==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "cssnano-utils": "^5.0.1", "postcss-value-parser": "^4.2.0" }, @@ -11280,12 +12371,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-unicode": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.3.tgz", - "integrity": "sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.4.tgz", + "integrity": "sha512-LvIURTi1sQoZqj8mEIE8R15yvM+OhbR1avynMtI9bUzj5gGKR/gfZFd8O7VMj0QgJaIFzxDwxGl/ASMYAkqO8g==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "postcss-value-parser": "^4.2.0" }, "engines": { @@ -11342,12 +12433,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-reduce-initial": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.3.tgz", - "integrity": "sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.4.tgz", + "integrity": "sha512-rdIC9IlMBn7zJo6puim58Xd++0HdbvHeHaPgXsimMfG1ijC5A9ULvNLSE0rUKVJOvNMcwewW4Ga21ngyJjY/+Q==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "caniuse-api": "^3.0.0" }, "engines": { @@ -11386,13 +12477,13 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-svgo": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.2.tgz", - "integrity": "sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.0.tgz", + "integrity": "sha512-KnAlfmhtoLz6IuU3Sij2ycusNs4jPW+QoFE5kuuUOK8awR6tMxZQrs5Ey3BUz7nFCzT3eqyFgqkyrHiaU2xx3w==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", - "svgo": "^3.3.2" + "svgo": "^4.0.0" }, "engines": { "node": "^18.12.0 || ^20.9.0 || >= 18" @@ -11417,12 +12508,12 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/stylehacks": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.5.tgz", - "integrity": "sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.6.tgz", + "integrity": "sha512-iitguKivmsueOmTO0wmxURXBP8uqOO+zikLGZ7Mm9e/94R4w5T999Js2taS/KBOnQ/wdC3jN3vNSrkGDrlnqQg==", "dev": true, "dependencies": { - "browserslist": "^4.24.5", + "browserslist": "^4.25.1", "postcss-selector-parser": "^7.1.0" }, "engines": { @@ -11432,10 +12523,35 @@ "postcss": "^8.4.32" } }, + "node_modules/css-minimizer-webpack-plugin/node_modules/svgo": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "dev": true, + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.4.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "dev": true, "dependencies": { "boolbase": "^1.0.0", @@ -11462,9 +12578,9 @@ } }, "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "dev": true, "engines": { "node": ">= 6" @@ -11838,6 +12954,11 @@ "url": "https://github.com/sponsors/kossnocorp" } }, + "node_modules/date-fns-jalali": { + "version": "4.1.0-0", + "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz", + "integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==" + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", @@ -11899,9 +13020,9 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "dev": true }, "node_modules/decompress-response": { @@ -12201,9 +13322,9 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, "node_modules/devtools-protocol": { - "version": "0.0.1467305", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1467305.tgz", - "integrity": "sha512-LxwMLqBoPPGpMdRL4NkLFRNy3QLp6Uqa7GNp1v6JaBheop2QrB9Q7q0A/q/CYYP9sBfZdHOyszVx4gc9zyk7ow==", + "version": "0.0.1478340", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1478340.tgz", + "integrity": "sha512-EqhRVWo+j3O1a5LEvZi5fFlBRhvciqYoCHpsEfPcIpA/Abh0W1LF+V3AIvQD9Z4Apj0+p3U07vb7uXfn2hm3HQ==", "dev": true }, "node_modules/diff": { @@ -12366,15 +13487,30 @@ } }, "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", + "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", "dev": true, "dependencies": { - "is-obj": "^2.0.0" + "type-fest": "^4.18.2" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dunder-proto": { @@ -12410,9 +13546,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.170", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz", - "integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==", + "version": "1.5.190", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.190.tgz", + "integrity": "sha512-k4McmnB2091YIsdCgkS0fMVMPOJgxl93ltFzaryXqwip1AaxeDqKCGLxkXODDA5Ab/D+tV5EL5+aTx76RvLRxw==", "dev": true }, "node_modules/emittery": { @@ -12854,9 +13990,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -12946,9 +14082,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -12987,29 +14123,29 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { @@ -13313,9 +14449,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.0.tgz", - "integrity": "sha512-8qsOYwkkGrahrgoUv76NZi23koqXOGiiEzXMrT8Q7VcYaUISR+5MorIUxfWqYXN0fN/31WbSrxCxFkVQ43wwrA==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.3.tgz", + "integrity": "sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", @@ -13546,21 +14682,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -13615,18 +14736,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -14182,9 +15291,9 @@ } }, "node_modules/find-process": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.10.tgz", - "integrity": "sha512-ncYFnWEIwL7PzmrK1yZtaccN8GhethD37RzBHG6iOZoFYB4vSmLLXfeWJjeN5nMvCJMjOtBvBBF8OgxEcikiZg==", + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.11.tgz", + "integrity": "sha512-mAOh9gGk9WZ4ip5UjV0o6Vb4SrfnAmtsFNzkMRH9HQiFXVQnDyQFrSHTK5UoG6E+KV+s+cIznbtwpfN41l2nFA==", "dev": true, "dependencies": { "chalk": "~4.1.2", @@ -14331,9 +15440,9 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "dependencies": { "asynckit": "^0.4.0", @@ -14355,6 +15464,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "dev": true + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -14413,9 +15528,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", "dev": true }, "node_modules/fs.realpath": { @@ -14608,9 +15723,9 @@ } }, "node_modules/get-uri": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", - "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", "dev": true, "dependencies": { "basic-ftp": "^5.0.2", @@ -14621,6 +15736,11 @@ "node": ">= 14" } }, + "node_modules/get-xpath": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/get-xpath/-/get-xpath-3.3.0.tgz", + "integrity": "sha512-AKbHVEHSlSDS9AJDmjfSxV010xSVRFzkS4UkGCb8CaGvorp83GCuKwcmzF/64CVp3M5wjgy9tc6y1uR2V+c5Xw==" + }, "node_modules/gettext-parser": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz", @@ -14732,11 +15852,30 @@ } }, "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { @@ -15002,9 +16141,9 @@ } }, "node_modules/hookified": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.9.1.tgz", - "integrity": "sha512-u3pxtGhKjcSXnGm1CX6aXS9xew535j3lkOCegbA6jdyh0BaAjTbXI4aslKstCr6zUNtoCxFGFKwjbSHdGrMB8g==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.10.0.tgz", + "integrity": "sha512-dJw0492Iddsj56U1JsSTm9E/0B/29a1AuoSLRAte8vQg/kaTGF3IgjEWT8c8yG4cC10+HisE1x5QAwR0Xwc+DA==", "dev": true }, "node_modules/hosted-git-info": { @@ -15098,14 +16237,14 @@ "dev": true }, "node_modules/html-react-parser": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.5.tgz", - "integrity": "sha512-bRPdv8KTqG9CEQPMNGksDqmbiRfVQeOidry8pVetdh/1jQ1Edx4KX5m0lWvDD89Pt4CqTYjK1BLz6NoNVxN/Uw==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.6.tgz", + "integrity": "sha512-qcpPWLaSvqXi+TndiHbCa+z8qt0tVzjMwFGFBAa41ggC+ZA5BHaMIeMJla9g3VSp4SmiZb9qyQbmbpHYpIfPOg==", "dependencies": { "domhandler": "5.0.3", "html-dom-parser": "5.1.1", "react-property": "2.0.2", - "style-to-js": "1.1.16" + "style-to-js": "1.1.17" }, "peerDependencies": { "@types/react": "0.14 || 15 || 16 || 17 || 18 || 19", @@ -15395,12 +16534,6 @@ "integrity": "sha512-W7+sO6/yhxy83L0G7xR8YAc5Z5QFtYEXXRV6EaE8tuYBZJnA3gVgp3q7X7muhLZVodeb9UfvjSbwt9VJwjIYAg==", "dev": true }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true - }, "node_modules/immutable": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", @@ -15430,6 +16563,18 @@ "node": ">=4" } }, + "node_modules/import-in-the-middle": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.2.tgz", + "integrity": "sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==", + "dev": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -15903,15 +17048,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -16090,12 +17226,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -17128,9 +18258,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.36.0.tgz", - "integrity": "sha512-A+9jP+IUmuQsNdsLdcg6Yt7voiMF/D4K83ew0OpJtpu+l34ef7LaohWV0Rc6KNvzw6ZDizkqfyB5JznZnzuKQA==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", "dev": true }, "node_modules/language-subtag-registry": { @@ -17199,9 +18329,9 @@ } }, "node_modules/lib0": { - "version": "0.2.108", - "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.108.tgz", - "integrity": "sha512-+3eK/B0SqYoZiQu9fNk4VEc6EX8cb0Li96tPGKgugzoGj/OdRdREtuTLvUW+mtinoB2mFiJjSqOJBIaMkAGhxQ==", + "version": "0.2.114", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.114.tgz", + "integrity": "sha512-gcxmNFzA4hv8UYi8j43uPlQ7CGcyMJ2KQb5kZASw6SnAKAf10hK12i2fjrS3Cl/ugZa5Ui6WwIu1/6MIXiHttQ==", "dependencies": { "isomorphic.js": "^0.2.4" }, @@ -17218,28 +18348,19 @@ "url": "https://github.com/sponsors/dmonad" } }, - "node_modules/lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, "node_modules/lighthouse": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-12.6.1.tgz", - "integrity": "sha512-85WDkjcXAVdlFem9Y6SSxqoKiz/89UsDZhLpeLJIsJ4LlHxw047XTZhlFJmjYCB7K5S1erSBAf5cYLcfyNbH3A==", + "version": "12.8.0", + "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-12.8.0.tgz", + "integrity": "sha512-MNmHLGRsaApxrigFl6M4FSvat8opl6K4MnBRWdU3yEaTH5pzrDSWjdIL2cBdCoV7OgAD1Cy/cdBiXR+ZzdsBNw==", "dev": true, "dependencies": { - "@paulirish/trace_engine": "0.0.53", - "@sentry/node": "^7.0.0", + "@paulirish/trace_engine": "0.0.57", + "@sentry/node": "^9.28.1", "axe-core": "^4.10.3", "chrome-launcher": "^1.2.0", - "configstore": "^5.0.1", + "configstore": "^7.0.0", "csp_evaluator": "1.1.5", - "devtools-protocol": "0.0.1467305", + "devtools-protocol": "0.0.1478340", "enquirer": "^2.3.6", "http-link-header": "^1.1.1", "intl-messageformat": "^10.5.3", @@ -17252,11 +18373,11 @@ "metaviewport-parser": "0.3.0", "open": "^8.4.0", "parse-cache-control": "1.0.1", - "puppeteer-core": "^24.10.0", + "puppeteer-core": "^24.10.2", "robots-parser": "^3.0.1", "semver": "^5.3.0", "speedline-core": "^1.4.3", - "third-party-web": "^0.26.6", + "third-party-web": "^0.27.0", "tldts-icann": "^6.1.16", "ws": "^7.0.0", "yargs": "^17.3.1", @@ -17303,9 +18424,9 @@ "dev": true }, "node_modules/lighthouse/node_modules/@puppeteer/browsers": { - "version": "2.10.5", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.5.tgz", - "integrity": "sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==", + "version": "2.10.6", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.6.tgz", + "integrity": "sha512-pHUn6ZRt39bP3698HFQlu2ZHCkS/lPcpv7fVQcGBSzNNygw171UXAKrCUhy+TEMw4lEttOKDgNpb04hwUAJeiQ==", "dev": true, "dependencies": { "debug": "^4.4.1", @@ -17313,7 +18434,7 @@ "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.7.2", - "tar-fs": "^3.0.8", + "tar-fs": "^3.1.0", "yargs": "^17.7.2" }, "bin": { @@ -17356,26 +18477,26 @@ } }, "node_modules/lighthouse/node_modules/puppeteer-core": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.10.1.tgz", - "integrity": "sha512-AE6doA9znmEEps/pC5lc9p0zejCdNLR6UBp3EZ49/15Nbvh+uklXxGox7Qh8/lFGqGVwxInl0TXmsOmIuIMwiQ==", + "version": "24.15.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.15.0.tgz", + "integrity": "sha512-2iy0iBeWbNyhgiCGd/wvGrDSo73emNFjSxYOcyAqYiagkYt5q4cPfVXaVDKBsukgc2fIIfLAalBZlaxldxdDYg==", "dev": true, "dependencies": { - "@puppeteer/browsers": "2.10.5", - "chromium-bidi": "5.1.0", + "@puppeteer/browsers": "2.10.6", + "chromium-bidi": "7.2.0", "debug": "^4.4.1", - "devtools-protocol": "0.0.1452169", + "devtools-protocol": "0.0.1464554", "typed-query-selector": "^2.12.0", - "ws": "^8.18.2" + "ws": "^8.18.3" }, "engines": { "node": ">=18" } }, "node_modules/lighthouse/node_modules/puppeteer-core/node_modules/chromium-bidi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-5.1.0.tgz", - "integrity": "sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-7.2.0.tgz", + "integrity": "sha512-gREyhyBstermK+0RbcJLbFhcQctg92AGgDe/h/taMJEOLRdtSswBAO9KmvltFSQWgM2LrwWu5SIuEUbdm3JsyQ==", "dev": true, "dependencies": { "mitt": "^3.0.1", @@ -17386,15 +18507,15 @@ } }, "node_modules/lighthouse/node_modules/puppeteer-core/node_modules/devtools-protocol": { - "version": "0.0.1452169", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1452169.tgz", - "integrity": "sha512-FOFDVMGrAUNp0dDKsAU1TorWJUx2JOU1k9xdgBKKJF3IBh/Uhl2yswG5r3TEAOrCiGY2QRp1e6LVDQrCsTKO4g==", + "version": "0.0.1464554", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1464554.tgz", + "integrity": "sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==", "dev": true }, "node_modules/lighthouse/node_modules/puppeteer-core/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -17443,9 +18564,9 @@ } }, "node_modules/lighthouse/node_modules/zod": { - "version": "3.25.67", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", - "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -17511,15 +18632,6 @@ "node": ">=8.9.0" } }, - "node_modules/localforage": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", - "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", - "dev": true, - "dependencies": { - "lie": "3.1.1" - } - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -18220,9 +19332,9 @@ } }, "node_modules/mixpanel-browser": { - "version": "2.65.0", - "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.65.0.tgz", - "integrity": "sha512-BtrVYqilloAqx3TIhoIpNikHznTocEy/z3QIf6WEiz4PFxrgI6LgSMFIVKqLqGZJ8svrPlHbpp/CJp5wQYUZWw==", + "version": "2.67.0", + "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.67.0.tgz", + "integrity": "sha512-LudY4eRIkvjEpAlIAg10i2T2mbtiKZ4XlMGbTyF1kcAhEqMa9JhEEdEcjxYPwiKhuMVSBM3RVkNCZaNqcnE4ww==", "dependencies": { "rrweb": "2.0.0-alpha.18" } @@ -18239,6 +19351,12 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "dev": true + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -18766,9 +19884,9 @@ } }, "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true, "engines": { "node": ">= 0.8" @@ -19101,9 +20219,9 @@ } }, "node_modules/pac-proxy-agent/node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "engines": { "node": ">= 14" @@ -19231,9 +20349,19 @@ } }, "node_modules/parsel-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/parsel-js/-/parsel-js-1.2.1.tgz", - "integrity": "sha512-omFBig09mUh/NjBGba4DxVFAsqCY4C/6UYIaJuDOxJw2GlpgUJdPlNF301971gCP3Gt727+F+NZIXN483VAKIg==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parsel-js/-/parsel-js-1.2.2.tgz", + "integrity": "sha512-AVJMlwQ4bL2Y0VvYJGk+Fp7eX4SCH2uFoNApmn4yKWACUewZ+alwW3tyoe1r5Z3aLYQTuAuPZIyGghMfO/Tlxw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/LeaVerou" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/leaverou" + } + ] }, "node_modules/parseurl": { "version": "1.3.3", @@ -19341,6 +20469,37 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "dev": true + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dev": true, + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -19495,13 +20654,13 @@ } }, "node_modules/playwright": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.0.tgz", - "integrity": "sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==", + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.1.tgz", + "integrity": "sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==", "dev": true, "peer": true, "dependencies": { - "playwright-core": "1.53.0" + "playwright-core": "1.54.1" }, "bin": { "playwright": "cli.js" @@ -19514,9 +20673,9 @@ } }, "node_modules/playwright-core": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.0.tgz", - "integrity": "sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==", + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.1.tgz", + "integrity": "sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==", "dev": true, "peer": true, "bin": { @@ -20219,6 +21378,45 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dev": true, + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -20229,9 +21427,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -20366,9 +21564,9 @@ } }, "node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "engines": { "node": ">= 14" @@ -20613,9 +21811,9 @@ } }, "node_modules/react-content-loader": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/react-content-loader/-/react-content-loader-7.0.2.tgz", - "integrity": "sha512-773S98JTyC8VB2nu7LXUhpHx8tZMieGxMcx3qTe7IkohT6Br7d9AXnIXs/wQ6IhlUdKQcw6JLKk1QKigYCWDRA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-content-loader/-/react-content-loader-7.1.1.tgz", + "integrity": "sha512-yNkqtd+15wXRLfDKZb5nTqDV2fPTG2kpUgeGRb+WBz43bU0j4DSGXETF0bnFr44fAoTPpm0Dya0WGdhpHSvtYA==", "engines": { "node": ">=10" }, @@ -20623,6 +21821,35 @@ "react": ">=16.0.0" } }, + "node_modules/react-day-picker": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.8.0.tgz", + "integrity": "sha512-E0yhhg7R+pdgbl/2toTb0xBhsEAtmAx1l7qjIWYfcxOy8w4rTSVfbtBoSzVVhPwKP/5E9iL38LivzoE3AQDhCQ==", + "dependencies": { + "@date-fns/tz": "1.2.0", + "date-fns": "4.1.0", + "date-fns-jalali": "4.1.0-0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/gpbl" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/react-day-picker/node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -20636,9 +21863,9 @@ } }, "node_modules/react-easy-crop": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-5.4.2.tgz", - "integrity": "sha512-V+GQUTkNWD8gK0mbZQfwTvcDxyCB4GS0cM36is8dAcvnsHY7DMEDP2D5IqHju55TOiCHwElJPVOYDgiu8BEiHQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-easy-crop/-/react-easy-crop-5.5.0.tgz", + "integrity": "sha512-OZzU+yXMhe69vLkDex+5QxcfT94FdcgVCyW2dBUw35ZoC3Is42TUxUy04w8nH1mfMKaizVdC3rh/wUfNW1mK4w==", "dependencies": { "normalize-wheel": "^1.0.1", "tslib": "^2.0.1" @@ -21033,6 +22260,20 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz", + "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -21502,6 +22743,12 @@ } } }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -21906,6 +23153,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "dev": true + }, "node_modules/showdown": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", @@ -22336,9 +23589,9 @@ } }, "node_modules/socks": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.6.tgz", + "integrity": "sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA==", "dev": true, "dependencies": { "ip-address": "^9.0.5", @@ -22364,9 +23617,9 @@ } }, "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, "engines": { "node": ">= 14" @@ -22882,6 +24135,12 @@ "node": ">=0.8.0" } }, + "node_modules/stubborn-fs": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/stubborn-fs/-/stubborn-fs-1.2.5.tgz", + "integrity": "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==", + "dev": true + }, "node_modules/style-search": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", @@ -22889,17 +24148,17 @@ "dev": true }, "node_modules/style-to-js": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", - "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", + "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==", "dependencies": { - "style-to-object": "1.0.8" + "style-to-object": "1.0.9" } }, "node_modules/style-to-object": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", - "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz", + "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==", "dependencies": { "inline-style-parser": "0.2.4" } @@ -22921,9 +24180,9 @@ } }, "node_modules/stylelint": { - "version": "16.20.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.20.0.tgz", - "integrity": "sha512-B5Myu9WRxrgKuLs3YyUXLP2H0mrbejwNxPmyADlACWwFsrL8Bmor/nTSh4OMae5sHjOz6gkSeccQH34gM4/nAw==", + "version": "16.22.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.22.0.tgz", + "integrity": "sha512-SVEMTdjKNV4ollUrIY9ordZ36zHv2/PHzPjfPMau370MlL2VYXeLgSNMMiEbLGRO8RmD2R8/BVUeF2DfnfkC0w==", "dev": true, "funding": [ { @@ -22936,9 +24195,9 @@ } ], "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3", "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", @@ -22949,21 +24208,21 @@ "debug": "^4.4.1", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^10.1.0", + "file-entry-cache": "^10.1.1", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^7.0.4", + "ignore": "^7.0.5", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.36.0", + "known-css-properties": "^0.37.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.3", + "postcss": "^8.5.6", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.0", @@ -23049,10 +24308,16 @@ "stylelint": "^16.0.2" } }, + "node_modules/stylelint-scss/node_modules/known-css-properties": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.36.0.tgz", + "integrity": "sha512-A+9jP+IUmuQsNdsLdcg6Yt7voiMF/D4K83ew0OpJtpu+l34ef7LaohWV0Rc6KNvzw6ZDizkqfyB5JznZnzuKQA==", + "dev": true + }, "node_modules/stylelint-scss/node_modules/mdn-data": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.21.0.tgz", - "integrity": "sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.23.0.tgz", + "integrity": "sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==", "dev": true }, "node_modules/stylelint-scss/node_modules/postcss-selector-parser": { @@ -23161,14 +24426,14 @@ } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.10.tgz", - "integrity": "sha512-B6/v1f0NwjxzmeOhzfXPGWpKBVA207LS7lehaVKQnFrVktcFRfkzjZZ2gwj2i1TkEUMQht7ZMJbABUT5N+V1Nw==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.11.tgz", + "integrity": "sha512-zfOAns94mp7bHG/vCn9Ru2eDCmIxVQ5dELUHKjHfDEOJmHNzE+uGa6208kfkgmtym4a0FFjEuFksCXFacbVhSg==", "dev": true, "dependencies": { - "cacheable": "^1.10.0", + "cacheable": "^1.10.1", "flatted": "^3.3.3", - "hookified": "^1.9.1" + "hookified": "^1.10.0" } }, "node_modules/stylelint/node_modules/global-modules": { @@ -23404,12 +24669,12 @@ "dev": true }, "node_modules/synckit": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", - "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", "dev": true, "dependencies": { - "@pkgr/core": "^0.2.4" + "@pkgr/core": "^0.2.9" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -23474,9 +24739,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.10.tgz", - "integrity": "sha512-C1SwlQGNLe/jPNqapK8epDsXME7CAJR5RL3GcE6KWx1d9OUByzoHVcbu1VPI8tevg9H8Alae0AApHHFGzrD5zA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", "dev": true, "dependencies": { "pump": "^3.0.0", @@ -23528,9 +24793,9 @@ } }, "node_modules/terser": { - "version": "5.43.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.0.tgz", - "integrity": "sha512-CqNNxKSGKSZCunSvwKLTs8u8sGGlp27sxNZ4quGh0QeNuyHM0JSEM/clM9Mf4zUp6J+tO2gUXhgXT2YMMkwfKQ==", + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -23685,9 +24950,9 @@ "dev": true }, "node_modules/third-party-web": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.26.7.tgz", - "integrity": "sha512-buUzX4sXC4efFX6xg2bw6/eZsCUh8qQwSavC4D9HpONMFlRbcHhD8Je5qwYdCpViR6q0qla2wPP+t91a2vgolg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.27.0.tgz", + "integrity": "sha512-h0JYX+dO2Zr3abCQpS6/uFjujaOjA1DyDzGQ41+oFn9VW/ARiq9g5ln7qEP9+BTzDpOMyIfsfj4OvfgXAsMUSA==", "dev": true }, "node_modules/through": { @@ -24039,15 +25304,6 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "dev": true }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -24165,18 +25421,6 @@ "node": ">=4" } }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -24538,21 +25782,22 @@ } }, "node_modules/webpack": { - "version": "5.99.9", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", - "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", + "version": "5.100.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.2.tgz", + "integrity": "sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.2", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -24566,7 +25811,7 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -24911,18 +26156,18 @@ } }, "node_modules/webpack-sources": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz", - "integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "engines": { "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -25010,6 +26255,12 @@ "node": ">=12" } }, + "node_modules/when-exit": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/when-exit/-/when-exit-2.1.4.tgz", + "integrity": "sha512-4rnvd3A1t16PWzrBUcSDZqcAmsUIy4minDXT/CZ8F2mVDgd65i4Aalimgz1aQkRGU0iH5eT5+6Rx2TK8o443Pg==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -25194,9 +26445,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "devOptional": true, "engines": { "node": ">=10.0.0" @@ -25215,12 +26466,15 @@ } }, "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/xml-name-validator": { @@ -25238,6 +26492,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y-indexeddb": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/y-indexeddb/-/y-indexeddb-9.0.12.tgz", diff --git a/package.json b/package.json index 2358a9f3..30fb8c99 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "slug": "pojo-accessibility", "homepage": "http://pojo.me/", "description": "", - "version": "3.5.0", + "version": "3.6.0", "scripts": { "build": "wp-scripts build", "start": "wp-scripts start", @@ -41,7 +41,7 @@ "dependencies": { "@elementor/design-tokens": "^1.1.4", "@elementor/icons": "^1.46.0", - "@elementor/ui": "^1.36.0", + "@elementor/ui": "^1.36.5", "@emotion/cache": "^11.14.0", "@emotion/react": "^11.14.0", "@mui/x-charts": "^7.27.0", @@ -58,6 +58,7 @@ "@wordpress/media-utils": "^5.22.0", "@wordpress/url": "^4.10.0", "clipboard-copy": "^4.0.1", + "get-xpath": "^3.3.0", "html-react-parser": "^5.2.2", "husky": "^9.1.6", "mixpanel-browser": "^2.58.0", diff --git a/pojo-accessibility.php b/pojo-accessibility.php index ccda980e..f65c6d32 100644 --- a/pojo-accessibility.php +++ b/pojo-accessibility.php @@ -5,7 +5,7 @@ * Description: Improve your website’s accessibility with ease. Customize capabilities such as text resizing, contrast modes, link highlights, and easily generate an accessibility statement to demonstrate your commitment to inclusivity. * Author: Elementor.com * Author URI: https://elementor.com/ - * Version: 3.5.0 + * Version: 3.6.0 * Text Domain: pojo-accessibility * Domain Path: /languages/ */ @@ -15,8 +15,7 @@ // Legacy define( 'POJO_A11Y_CUSTOMIZER_OPTIONS', 'pojo_a11y_customizer_options' ); - -define( 'EA11Y_VERSION', '3.5.0' ); +define( 'EA11Y_VERSION', '3.6.0' ); define( 'EA11Y_MAIN_FILE', __FILE__ ); define( 'EA11Y_BASE', plugin_basename( EA11Y_MAIN_FILE ) ); define( 'EA11Y_PATH', plugin_dir_path( __FILE__ ) ); diff --git a/readme.txt b/readme.txt index eff6b0c3..482b4fc8 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: Web Accessibility, Accessibility, A11Y, WCAG, Accessibility Statement Requires at least: 6.6 Tested up to: 6.8 Requires PHP: 7.4 -Stable tag: 3.5.0 +Stable tag: 3.6.0 License: GPLv2 or later Ally: Make your site more inclusive by scanning for accessibility violations, fixing them easily, and adding a usability widget and accessibility statement. @@ -174,6 +174,9 @@ Yes. You can rescan a URL as often as needed. Results update each time based on = What are AI fixes? = These are smart suggestions generated by Ally to help you resolve issues more efficiently-like automatically suggesting alternative text for images. AI fixes are available only on paid plans and use credits. += How can I report security bugs? = +You can report security bugs through the Patchstack Vulnerability Disclosure Program. The Patchstack team help validate, triage and handle any security vulnerabilities. [Report a security vulnerability](https://patchstack.com/database/wordpress/plugin/pojo-accessibility/vdp). + == Screenshots == @@ -184,6 +187,28 @@ These are smart suggestions generated by Ally to help you resolve issues more ef 5. Widget on Site: This is how the accessibility widget appears on a live website. == Changelog == + += 3.6.0 - 2025-08-02 = +* New: Smart color contrast remediation flow in the accessibility assistant +* Tweak: Updated scan dashboard to show open issues and issue breakdown by category +* Tweak: Tooltip on analytics tab encouraging tracking activation +* Tweak: Improve accessibility column in WP admin for better user experience +* Fix: Added WPML compatibility +* Fix: WooCommerce AJAX conflict + += 3.5.2 - 2025-07-28 = +* Tweak: Improved performance by enqueuing Assistant only when logged in +* Fix: Admin post columns offset warning + += 3.5.1 - 2025-07-23 = +* Tweak: Admin panel UI updates +* Tweak: Assistant UI updates +* Tweak: Ensure case sensitive attributes in remediations +* Fix: Assistant accessibility issues +* Fix: Custom Icon issue in edge cases +* Fix: Critical Error on plugin conflict + + = 3.5.0 - 2025-07-08 = * New: Introducing URL Scanner – find 180+ issues instantly (WCAG 2.1 AA) * New: Introducing Remediation Engine – get in-context guided, AI-powered accessibility fixes diff --git a/ruleset.xml b/ruleset.xml index 654bb9fe..475e13b3 100644 --- a/ruleset.xml +++ b/ruleset.xml @@ -12,6 +12,13 @@ node_modules/ includes/libraries/ + + . + + + + +